Java使用RSA的公钥加密,私钥解密;私钥加密,公钥解密
import lombok
.extern
.slf4j
.Slf4j
;
import org
.apache
.commons
.codec
.binary
.Base64
;
import org
.springframework
.beans
.factory
.annotation
.Autowired
;
import org
.springframework
.stereotype
.Component
;
import org
.system
.common
.util
.RedisUtil
;
import javax
.crypto
.Cipher
;
import java
.security
.*
;
import java
.security
.interfaces
.RSAPrivateKey
;
import java
.security
.interfaces
.RSAPublicKey
;
import java
.security
.spec
.PKCS8EncodedKeySpec
;
import java
.security
.spec
.X509EncodedKeySpec
;
import java
.util
.HashMap
;
import java
.util
.Map
;
@Slf4j
public class RSAEncrypt {
public static void main(String
[] args
) throws Exception
{
String point
= "xxx";
Map
<String, String> keyMap
= new HashMap<>();
keyMap
.put("publicKey", "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOUDwJVY1JMY4oSHM1+VKeYZ5T2LjQ4wvENnt0TlRoOYDrUen4Nm3GbVKiGTot76gu7xYL1X9PQvDnYLpUVu0mA2oLrXWZj2ByTW83Ehdc5Y9aLXtNzmm4e6PXtuEtXk2sqUZz+XtBBAUMAne4J9G9DAZVPLFxUUJyzVb9cnK6NQIDAQAB");
keyMap
.put("privateKey", "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAM5QPAlVjUkxjihIczX5Up5hnlPYuNDjC8Q2e3ROVGg5gOtR6fg2bcZtUqIZOi3vqC7vFgvVf09C8OdgulRW7SYDagutdZmPYHJNbzcSF1zlj1ote03Oabh7o9e24S1eTaypRnP5e0EEBQwCd7gn0b0MBlU8sXFRQnLNVv1ycro1AgMBAAECgYAKkJlCcRsXEG6TKYKc1POiIKWW7ZYpPDcyCQgxYIF6BNfRNRSiHUdpzddZbalJCOi33o5mdLxcNrVXY+CmyPzDyeyNWWX8UcL2Wud8vRlWU7kQ+YcCVyS/nqRLBpHb0QgW7bqzb7fRpnmqhfj+A9hzRaoKxsZ8EWQfvN5UcdmQgQJBAPyTXzHcicK6gsgaXVo8awXsKxT6/bVAq7+FO/F4ckflS3oyABFNnqVRTC3nuQsU6nq3fu1kDwa03NcAa5zZaykCQQDRHEw4N0pnGKdecKTjBlD95B9WI0KCMWHpSOTIZJUIEvKXANX5BFaGHY01BNxDmwVcuecHgG2XH/WyIzVeJEQtAkEA8WM/NX4aQvrRhsB7u4PGnPBq9DA0TQeznOSOt2ZvgfrIOc6TdfYCyuh5r92oYcjpl8LLEcHxAm3UKb8DGfJIkQJAAjyYQB2vSQ0FdUglK1x870pKX4R/CJ94maMy90XEJlL1j1Ht9/zo5ARa509G/94fn49JflYMVgp8eUxRHNGsfQJBAKm39ZUaFyuDSpRINHZNHfldasmy9hLyXdTb3sLFj/bPaq0MyORAZPqq6XCu+nnIhVKVyADbXb+8T5kn70lzIbg=");
String publicKey
= keyMap
.get("publicKey");
String privateKey
= keyMap
.get("privateKey");
System
.out
.println(publicKey
);
System
.out
.println(privateKey
);
String message
= "我是测试";
System
.out
.println("前端请求的原数据\n"+message
);
String messageEn
= publicKeyEncrypt(message
, publicKey
,point
);
System
.out
.println("前端请求的加密:\n" + messageEn
);
String messageDe
= privateKeyDecrypt(messageEn
, privateKey
,point
);
System
.out
.println("后端解密出来的数据:\n" + messageDe
);
System
.out
.println("=====================");
String s
= privateKeyEncrypt(messageDe
, privateKey
,point
);
System
.out
.println("后端返回的加密数据\n"+s
);
String s1
= publicKeyDecrypt(s
, publicKey
,point
);
System
.out
.println("前端解密出来显示的数据\n"+s1
);
}
public static Map
<String, String> genKeyPair(String point
) throws NoSuchAlgorithmException
{
log
.info("{}|开始生成公私钥",point
);
KeyPairGenerator keyPairGen
= KeyPairGenerator
.getInstance("RSA");
keyPairGen
.initialize(1024, new SecureRandom());
KeyPair keyPair
= keyPairGen
.generateKeyPair();
RSAPrivateKey privateKey
= (RSAPrivateKey
) keyPair
.getPrivate();
RSAPublicKey publicKey
= (RSAPublicKey
) keyPair
.getPublic();
String publicKeyString
= new String(Base64
.encodeBase64(publicKey
.getEncoded()));
String privateKeyString
= new String(Base64
.encodeBase64((privateKey
.getEncoded())));
Map
<String, String> map
= new HashMap<>();
map
.put("publicKey", publicKeyString
);
map
.put("privateKey", privateKeyString
);
log
.info("{}|生成的公私钥|map:{}",point
,map
);
return map
;
}
public static String
publicKeyEncrypt(String str
, String publicKey
,String point
) throws Exception
{
log
.info("{}|RSA公钥加密前的数据|str:{}|publicKey:{}",point
,str
,publicKey
);
byte[] decoded
= Base64
.decodeBase64(publicKey
);
RSAPublicKey pubKey
= (RSAPublicKey
) KeyFactory
.getInstance("RSA").
generatePublic(new X509EncodedKeySpec(decoded
));
Cipher cipher
= Cipher
.getInstance("RSA");
cipher
.init(Cipher
.ENCRYPT_MODE
, pubKey
);
String outStr
= Base64
.encodeBase64String(cipher
.doFinal(str
.getBytes("UTF-8")));
log
.info("{}|公钥加密后的数据|outStr:{}",point
,outStr
);
return outStr
;
}
public static String
privateKeyDecrypt(String str
, String privateKey
, String point
) throws Exception
{
log
.info("{}|RSA私钥解密前的数据|str:{}|privateKey:{}",point
,str
,privateKey
);
byte[] inputByte
= Base64
.decodeBase64(str
.getBytes("UTF-8"));
byte[] decoded
= Base64
.decodeBase64(privateKey
);
RSAPrivateKey priKey
= (RSAPrivateKey
) KeyFactory
.getInstance("RSA")
.generatePrivate(new PKCS8EncodedKeySpec(decoded
));
Cipher cipher
= Cipher
.getInstance("RSA");
cipher
.init(Cipher
.DECRYPT_MODE
, priKey
);
String outStr
= new String(cipher
.doFinal(inputByte
));
log
.info("{}|RSA私钥解密后的数据|outStr:{}",point
,outStr
);
return outStr
;
}
public static String
privateKeyEncrypt(String str
, String privateKey
,String point
) throws Exception
{
log
.info("{}|RSA私钥加密前的数据|str:{}|publicKey:{}",point
,str
,privateKey
);
byte[] decoded
= Base64
.decodeBase64(privateKey
);
PrivateKey priKey
= KeyFactory
.getInstance("RSA").
generatePrivate(new PKCS8EncodedKeySpec(decoded
));
Cipher cipher
= Cipher
.getInstance("RSA");
cipher
.init(Cipher
.ENCRYPT_MODE
, priKey
);
String outStr
= Base64
.encodeBase64String(cipher
.doFinal(str
.getBytes()));
log
.info("{}|RSA私钥加密后的数据|outStr:{}",point
,outStr
);
return outStr
;
}
public static String
publicKeyDecrypt(String str
, String publicKey
,String point
) throws Exception
{
log
.info("{}|RSA公钥解密前的数据|str:{}|publicKey:{}",point
,str
,publicKey
);
byte[] inputByte
= Base64
.decodeBase64(str
.getBytes("UTF-8"));
byte[] decoded
= Base64
.decodeBase64(publicKey
);
PublicKey pubKey
= KeyFactory
.getInstance("RSA")
.generatePublic(new X509EncodedKeySpec(decoded
));
Cipher cipher
= Cipher
.getInstance("RSA");
cipher
.init(Cipher
.DECRYPT_MODE
, pubKey
);
String outStr
= new String(cipher
.doFinal(inputByte
));
log
.info("{}|RSA公钥解密后的数据|outStr:{}",point
,outStr
);
return outStr
;
}
}
通过RSA进行前端与后端的交互, 前端获取到公钥 后端获取到私钥 前端发起请求,通过公钥加密,后端用私钥解密 后端通知前端,通过私钥加密,前端通过公钥解密
前端通过公钥解密的逻辑没有测试过,找到的资源地址为: https://github.com/kjur/jsrsasign/blob/master/src/rsasign-1.2.js#L234
错误信息: Data must not be longer than 128 bytes 当加解密的数据长度过长,需要对数据进行分割 加密则117字节,解密则128字节
public static String
publicKeyEncrypt(String str
, String publicKey
, String point
) throws Exception
{
log
.info("{}|RSA公钥加密前的数据|str:{}|publicKey:{}", point
, str
, publicKey
);
byte[] decoded
= Base64
.decodeBase64(publicKey
);
RSAPublicKey pubKey
= (RSAPublicKey
) KeyFactory
.getInstance("RSA").
generatePublic(new X509EncodedKeySpec(decoded
));
Cipher cipher
= Cipher
.getInstance("RSA");
cipher
.init(Cipher
.ENCRYPT_MODE
, pubKey
);
byte[] resultBytes
= getMaxResultEncrypt(str
, point
, cipher
);
String outStr
= Base64
.encodeBase64String(resultBytes
);
log
.info("{}|公钥加密后的数据|outStr:{}", point
, outStr
);
return outStr
;
}
private static byte[] getMaxResultEncrypt(String str
, String point
, Cipher cipher
) throws IllegalBlockSizeException
, BadPaddingException
{
byte[] inputArray
= str
.getBytes();
int inputLength
= inputArray
.length
;
log
.info("{}|加密字节数|inputLength:{}", point
, inputLength
);
int MAX_ENCRYPT_BLOCK
= 117;
int offSet
= 0;
byte[] resultBytes
= {};
byte[] cache
= {};
while (inputLength
- offSet
> 0) {
if (inputLength
- offSet
> MAX_ENCRYPT_BLOCK
) {
cache
= cipher
.doFinal(inputArray
, offSet
, MAX_ENCRYPT_BLOCK
);
offSet
+= MAX_ENCRYPT_BLOCK
;
} else {
cache
= cipher
.doFinal(inputArray
, offSet
, inputLength
- offSet
);
offSet
= inputLength
;
}
resultBytes
= Arrays
.copyOf(resultBytes
, resultBytes
.length
+ cache
.length
);
System
.arraycopy(cache
, 0, resultBytes
, resultBytes
.length
- cache
.length
, cache
.length
);
}
return resultBytes
;
}
public static String
privateKeyDecrypt(String str
, String privateKey
, String point
) throws Exception
{
log
.info("{}|RSA私钥解密前的数据|str:{}|privateKey:{}", point
, str
, privateKey
);
byte[] inputByte
= Base64
.decodeBase64(str
.getBytes("UTF-8"));
byte[] decoded
= Base64
.decodeBase64(privateKey
);
RSAPrivateKey priKey
= (RSAPrivateKey
) KeyFactory
.getInstance("RSA")
.generatePrivate(new PKCS8EncodedKeySpec(decoded
));
Cipher cipher
= Cipher
.getInstance("RSA");
cipher
.init(Cipher
.DECRYPT_MODE
, priKey
);
String outStr
= new String(getMaxResultDecrypt(str
, point
, cipher
));
log
.info("{}|RSA私钥解密后的数据|outStr:{}", point
, outStr
);
return outStr
;
}
private static byte[] getMaxResultDecrypt(String str
, String point
, Cipher cipher
) throws IllegalBlockSizeException
, BadPaddingException
, UnsupportedEncodingException
{
byte[] inputArray
= Base64
.decodeBase64(str
.getBytes("UTF-8"));
int inputLength
= inputArray
.length
;
log
.info("{}|解密字节数|inputLength:{}", point
, inputLength
);
int MAX_ENCRYPT_BLOCK
= 128;
int offSet
= 0;
byte[] resultBytes
= {};
byte[] cache
= {};
while (inputLength
- offSet
> 0) {
if (inputLength
- offSet
> MAX_ENCRYPT_BLOCK
) {
cache
= cipher
.doFinal(inputArray
, offSet
, MAX_ENCRYPT_BLOCK
);
offSet
+= MAX_ENCRYPT_BLOCK
;
} else {
cache
= cipher
.doFinal(inputArray
, offSet
, inputLength
- offSet
);
offSet
= inputLength
;
}
resultBytes
= Arrays
.copyOf(resultBytes
, resultBytes
.length
+ cache
.length
);
System
.arraycopy(cache
, 0, resultBytes
, resultBytes
.length
- cache
.length
, cache
.length
);
}
return resultBytes
;
}