美文网首页
5-非对称加密

5-非对称加密

作者: awesome丁 | 来源:发表于2017-09-07 17:38 被阅读0次

公钥与私钥

非对称加密与对称加密主要的区别在于非对称加密在加密和解密时采用不同的密钥,一个公开,称为公钥,可以通过非安全通道发放,另一个保密,称为私钥,由发放者自己保存。公钥与私钥成对出现,用公钥加密的数据,只能由私钥解密,用私钥加密的数据,只能由公钥解密。

非对称加密解决了对称加密的密钥分配与传递问题,并提高了算法的安全性,但是加解密速度比对称加密慢很多,所以通常用非对称加密传递对称加密的密钥,而使用对称加密传递数据

RSA算法

RSA算法是一种典型的非对称加密算法,也是目前最有影响力的非对称加密算法,该算法于1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出,RSA就是他们三个人的名字简写。RSA算法的密钥为512到65535位且必须为64位的倍数。

两种使用场景

加密: 不希望别人看到我的消息,只有我才能解密,所以可得出公钥负责加密,私钥负责解密;
签名:不希望有人冒充我发消息,只有我才能发布这个签名,所以可得出私钥负责签名,公钥负责验证。

注意

  1. 采用base64编码公钥私钥字节数组,以无乱码的方式存储公钥私钥字符串
  2. 采用base64编码密文字节数组,得到无乱码字符串方便网络传输
import org.apache.commons.codec.binary.Base64;
import org.junit.Test;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
/**
 * Created by tingkl on 2017/9/5.
 */
public class RSA {
    private static String src = "tingkl security rsa";
    private static String publicKeyBase64;
    private static String privateKeyBase64;

    static {
        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(512);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();

            RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
            RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();

            publicKeyBase64 = Base64.encodeBase64String(rsaPublicKey.getEncoded());
            privateKeyBase64 = Base64.encodeBase64String(rsaPrivateKey.getEncoded());

            System.out.println("Public Key:" + Base64.encodeBase64String(rsaPublicKey.getEncoded()));
            System.out.println("Private Key:" + Base64.encodeBase64String(rsaPrivateKey.getEncoded()));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

    }

    @Test
    public void jdkRSA() {
        try {
            //1.私钥加密,公钥解密----加密
            PrivateKey privateKey = getPrivateKey(Base64.decodeBase64(privateKeyBase64));
            byte[] encryptBytesToSend = encrypt(src, privateKey);
            String encryptBytesBase64 = Base64.encodeBase64String(encryptBytesToSend);

            System.out.println("私钥加密---send:" + encryptBytesBase64);
            //2.私钥加密,公钥解密----解密

            byte[] encryptBytesReceived = Base64.decodeBase64(encryptBytesBase64);
            PublicKey publicKey = getPublicKey(Base64.decodeBase64(publicKeyBase64));
            String result = decrypt(encryptBytesReceived, publicKey);
            System.out.println("公钥解密---receive:" + result);

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        }
    }

    private static String decrypt(byte[] encryptBytesReceived, Key key) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, key);

        byte[] result = cipher.doFinal(encryptBytesReceived);
        return new String(result);
    }


    private static byte[] encrypt(String src, Key key) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] result = cipher.doFinal(src.getBytes());
        return result;
    }

    private static PrivateKey getPrivateKey(byte[] bytes) throws NoSuchAlgorithmException, InvalidKeySpecException {
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(bytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        return privateKey;
    }

    private static PublicKey getPublicKey(byte[] bytes) throws NoSuchAlgorithmException, InvalidKeySpecException {
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(bytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
        return publicKey;
    }


    @Test
    public void jdkRSA2() {
        try {
            //1.公钥加密,私钥解密----加密
            PublicKey publicKey = getPublicKey(Base64.decodeBase64(publicKeyBase64));
            byte[] encryptBytesToSend = encrypt(src, publicKey);
            String encryptBytesBase64 = Base64.encodeBase64String(encryptBytesToSend);
            System.out.println("公钥加密---send:" + encryptBytesBase64);
            //2.公钥加密,私钥解密----解密
            byte[] encryptBytesReceived = Base64.decodeBase64(encryptBytesBase64);
            PrivateKey privateKey = getPrivateKey(Base64.decodeBase64(privateKeyBase64));
            String result = decrypt(encryptBytesReceived, privateKey);
            System.out.println("私钥解密---receive:" + result);

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        }
    }
}

相关文章

  • 5-非对称加密

    公钥与私钥 非对称加密与对称加密主要的区别在于非对称加密在加密和解密时采用不同的密钥,一个公开,称为公钥,可以通过...

  • 第四篇:非对称加密及RSA加密算法

    目录一、非对称加密 1、什么是非对称加密? 2、对称加密的工作过程 3、非对称加密的优点 4、非对称加密的不足二、...

  • https交互流程简述

    https使用到的加密算法 对称加密非对称加密 通过非对称加密,交换对称加密的密钥,之后采用对称加密传输非对称加密...

  • ios开发之证书和签名机制(一)

    非对称加密和摘要 1、非对称加密的特性和用法 1) 非对称加密算法(RSA):非对称加密算法指加密秘钥和解密秘钥是...

  • 学习笔记:HTTPS协议原理

    对称加密和非对称加密 加密分两种,对称加密和非对称加密。对称加密是指加密的双方使用同一个密钥加密和解密数据。非对称...

  • iOS逆向攻防之HASH,数字签名,对称加密算法

    在密码学中,加密部分主要分为对称加密和非对称加密,非对称加密主要有RSA非对称加密(使用公钥/私钥来加密解密),对...

  • iOS逆向攻防之HASH,数字签名,对称加密算法

    在密码学中,加密部分主要分为对称加密和非对称加密,非对称加密主要有RSA非对称加密(使用公钥/私钥来加密解密),对...

  • Https加密原理图解

    1. 为什么要用对称加密+非对称加密? 结合对称加密的快和非对称加密的安全。 2. 为什么不能只用非对称加密? 如...

  • kotlin版本RSA非对称加密解密与分段加密解密

    基于kotlin语言的RSA非对称加密解密与分段加密解密 RSA非对称加密 RSA非对称加密的具体算法与来源我就不...

  • 4-对称加密

    对称加密与非对称加密 按照密钥的特征不同, 密码体制分为对称密码体制和非对称密码体制。对称加密和非对称加密都是可逆...

网友评论

      本文标题:5-非对称加密

      本文链接:https://www.haomeiwen.com/subject/pcoijxtx.html