非对称加密解密RSA的实现例子

2020-09-09  本文已影响0人  西5d

背景

最近有接触到加密相关的内容,本期以非对称加密为例子,做个简单的总结和记录。首先了解下非对称加密,简单来说非对称指的是加密和解密用不同的秘钥,典型的RSA,这个算法名称是基于三个发明人的名字首字母取的;而对称加密必须要在加解密使用相同的秘钥,典型的AES。这里细节不多展开阐述,涉及到很多数学原理,如大数的质因数分解等,感兴趣的可以找找李永乐等网上比较优秀的科普。这篇文章只是java原生实现的加解密例子。至于其他的如md5,hash等,如果从主观可读的角度来说,也可以称为加密。

描述

如下的示例是使用Java原生实现RSA的加密解密,包括用公钥加密,然后私钥解密;或者使用私钥加密,然后公钥解密。注意不同key大小,限制的解密内容大小也不一样,感兴趣的同学可以试试修改key大小和加密内容长度来试试。还有要注意的是RSA加密有一定的性能损耗。

代码

import lombok.Data;
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.RSAPrivateKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

@Data
public class CipherTest {

    public static RSAPublicKey rsaPublicKey;
    public static RSAPrivateKey rsaPrivateKey;

    static {
        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(2048);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
            rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();

            System.out.println("pub:" + Base64.getEncoder().encodeToString(rsaPublicKey.getEncoded()));
            System.out.println("pri:" + Base64.getEncoder().encodeToString(rsaPrivateKey.getEncoded()));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }

    //加密数据
    String text = "abcdefghijklmn";

    //公钥加密私钥解密
    @Test
    public void securityByPub() {
        String s = encodeByPub(text);
        System.out.println(s);
        System.out.println(decodeByPri(s));
    }

    //私钥加密公钥解密
    @Test
    public void securityByPri() {
        String s = encodeByPri(text);
        System.out.println(s);
        System.out.println(decodeByPub(s));
    }

    //公钥加密
    private String encodeByPub(String text) {
        try {
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] res = cipher.doFinal(text.getBytes());
            return Base64.getEncoder().encodeToString(res);
        } catch (NoSuchAlgorithmException | InvalidKeySpecException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) {
            e.printStackTrace();
        }
        return null;
    }

    //私钥加密
    private String encodeByPri(String text) {
        try {
            RSAPrivateKeySpec rsaPrivateKeySpec = new RSAPrivateKeySpec(rsaPrivateKey.getModulus(), rsaPrivateKey.getPrivateExponent());
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey privateKey = keyFactory.generatePrivate(rsaPrivateKeySpec);
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, privateKey);
            byte[] res = cipher.doFinal(text.getBytes());
            return Base64.getEncoder().encodeToString(res);
        } catch (NoSuchAlgorithmException | InvalidKeySpecException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) {
            e.printStackTrace();
        }
        return null;
    }

    //私钥解密
    private String decodeByPri(String encrypt) {
        try {
            byte[] data = Base64.getDecoder().decode(encrypt);
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] res = cipher.doFinal(data);
            return new String(res);
        } catch (NoSuchAlgorithmException | InvalidKeySpecException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) {
            e.printStackTrace();
        }
        return null;
    }

    //公钥解密
    private String decodeByPub(String encrypt) {
        try {
            byte[] data = Base64.getDecoder().decode(encrypt);
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, publicKey);
            byte[] res = cipher.doFinal(data);
            return new String(res);
        } catch (NoSuchAlgorithmException | InvalidKeySpecException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) {
            e.printStackTrace();
        }
        return null;
    }

}

总结

想了解原理相关的内容可以看如下的参考内容。
[1]. RSA原理

上一篇下一篇

猜你喜欢

热点阅读