RSA加密
- 密钥生成
使用git bash here 生成私钥,长度为1024bit
// 生成private.pem 私钥
openssl genrsa -out private.pem 1024
从私钥中提取公钥
//生成public.pem公钥
openssl rsa -pubout -in private.pem -out public.pem
1. 前端 --- jsencrypt.js
☆☆☆☆☆ RSA 加密明文最大长度 117字节
☆☆☆☆☆ 解密要求秘文最大长度128字节.....
var encryptor = new JSEncrypt();
var publicKey = '-----BEGIN PUBLIC KEY-----xxxxxxx-----END PUBLIC KEY-----';
encryptor.setPublicKey(publicKey);
var rsaPassword = encryptor.encrypt('1234');
console.log("enc:::"+rsaPassword);
var decrypt = new JSEncrypt();
var priKey = '-----BEGIN RSA PRIVATE KEY-----xxxxxx-----END RSA PRIVATE KEY-----';
decrypt.setPrivateKey(priKey);
var uncrypted = decrypt.decrypt(rsaPassword);
console.log("unc:::"+uncrypted);
//jsonstr 按照key进行排序
function jsonSort(jsonobj){
var jsonobj = JSON.parse(jsonobj);
let arr = [];
for(var key in jsonobj){
arr.push(key);
}
arr.sort();
let resObj = {};
for (var i in arr){
resObj[arr[i]] = jsonobj[arr[i]];
}
return JSON.stringify(resObj);
}
2. 服务端 --- aes rsa
package cn.xxx.xxx.utils;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.lang3.StringUtils;
import java.util.Base64;
//import sun.misc.BASE64Decoder;
//import sun.misc.BASE64Encoder;
/**
* @Title: AESUtils.java
* @Package xxx
* @Description: TODO
* @author xxx
* @date 2017年9月11日 下午5:48:17
* @version V1.0
*/
public class AESUtils {
private static final String encodeRules = "xxxxx";
/**
* 加密
* 1.构造密钥生成器
* 2.根据ecnodeRules规则初始化密钥生成器
* 3.产生密钥
* 4.创建和初始化密码器
* 5.内容加密
* 6.返回字符串
*/
public static String AESEncode(String content) {
try {
//1.构造密钥生成器,指定为AES算法,不区分大小写
KeyGenerator keygen = KeyGenerator.getInstance("AES");
//2.根据ecnodeRules规则初始化密钥生成器
//生成一个128位的随机源,根据传入的字节数组
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
random.setSeed(encodeRules.getBytes());
keygen.init(128, random);
//3.产生原始对称密钥
SecretKey original_key = keygen.generateKey();
//4.获得原始对称密钥的字节数组
byte[] raw = original_key.getEncoded();
//5.根据字节数组生成AES密钥
SecretKey key = new SecretKeySpec(raw, "AES");
//6.根据指定算法AES自成密码器
Cipher cipher = Cipher.getInstance("AES");
//7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作,第二个参数为使用的KEY
cipher.init(Cipher.ENCRYPT_MODE, key);
//8.获取加密内容的字节数组(这里要设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码
byte[] byte_encode = content.getBytes("utf-8");
//9.根据密码器的初始化方式--加密:将数据加密
byte[] byte_AES = cipher.doFinal(byte_encode);
//10.将加密后的数据转换为字符串
//这里用Base64Encoder中会找不到包
//解决办法:
//在项目的Build path中先移除JRE System Library,再添加库JRE System Library,重新编译后就一切正常了。
String AES_encode = new String(Base64.getEncoder().encodeToString(byte_AES));
//11.将字符串返回
return AES_encode;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
//如果有错就返加nulll
return null;
}
/**
* AES加密
* @param content 待加密的内容
* @param encryptKey 加密密钥
* @return 加密后的byte[]
* @throws Exception
*/
public static byte[] aesEncryptToBytes(String content, String encryptKey) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
// kgen.init(128, new SecureRandom(encryptKey.getBytes()));
kgen.init(128);
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(), "AES"));
return cipher.doFinal(content.getBytes("utf-8"));
}
/**
* 解密
* 解密过程:
* 1.同加密1-4步
* 2.将加密后的字符串反纺成byte[]数组
* 3.将加密内容解密
*/
public static String AESDecode(String content) {
try {
//1.构造密钥生成器,指定为AES算法,不区分大小写
KeyGenerator keygen = KeyGenerator.getInstance("AES");
//2.根据ecnodeRules规则初始化密钥生成器
//生成一个128位的随机源,根据传入的字节数组
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
random.setSeed(encodeRules.getBytes());
keygen.init(128, random);
//3.产生原始对称密钥
SecretKey original_key = keygen.generateKey();
//4.获得原始对称密钥的字节数组
byte[] raw = original_key.getEncoded();
//5.根据字节数组生成AES密钥
SecretKey key = new SecretKeySpec(raw, "AES");
//6.根据指定算法AES自成密码器
Cipher cipher = Cipher.getInstance("AES");
//7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密(Decrypt_mode)操作,第二个参数为使用的KEY
cipher.init(Cipher.DECRYPT_MODE, key);
//8.将加密并编码后的内容解码成字节数组
byte[] byte_content = Base64.getDecoder().decode(content);
/*
* 解密
*/
byte[] byte_decode = cipher.doFinal(byte_content);
String AES_decode = new String(byte_decode, "utf-8");
return AES_decode;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
//如果有错就返加nulll
return null;
}
/**
* AES解密
* @param encryptBytes 待解密的byte[]
* @param decryptKey 解密密钥
* @return 解密后的String
* @throws Exception
*/
public static String aesDecryptByBytes(byte[] encryptBytes, String decryptKey) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
// kgen.init(128, new SecureRandom(decryptKey.getBytes()));
kgen.init(128);
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptKey.getBytes(), "AES"));
byte[] decryptBytes = cipher.doFinal(encryptBytes);
return new String(decryptBytes);
}
/**
* base 64 加密
* @param bytes 待编码的byte[]
* @return 编码后的base 64 code
*/
public static String base64Encode(byte[] bytes){
return Base64.getEncoder().encodeToString(bytes);
}
/**
* base 64 解密
* @param base64Code 待解码的base 64 code
* @return 解码后的byte[]
* @throws Exception
*/
public static byte[] base64Decode(String base64Code) throws Exception{
return StringUtils.isEmpty(base64Code) ? null : Base64.getDecoder().decode(base64Code);
}
/**
* 将base 64 code AES解密
* @param encryptStr 待解密的base 64 code
* @param decryptKey 解密密钥
* @return 解密后的string
* @throws Exception
*/
public static String aesDecrypt(String encryptStr, String decryptKey) throws Exception {
return StringUtils.isEmpty(encryptStr) ? null : aesDecryptByBytes(base64Decode(encryptStr), decryptKey);
}
/**
* AES加密为base 64 code
* @param content 待加密的内容
* @param encryptKey 加密密钥
* @return 加密后的base 64 code
* @throws Exception
*/
public static String aesEncrypt(String content, String encryptKey) throws Exception {
return base64Encode(aesEncryptToBytes(content, encryptKey));
}
}
package cn.xxx.xxx.utils;
import lombok.Data;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
public class RSAUtils {
@Data
public static class RSAKeyPair {
String publicKey;
String privateKey;
}
public static RSAKeyPair getKeyPair() throws Exception{
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(1024, new SecureRandom());
KeyPair keyPair = keyPairGen.generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();
String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
String privateKeyString = new String(Base64.encodeBase64(privateKey.getEncoded()));
RSAKeyPair rsaKeyPair = new RSAKeyPair();
rsaKeyPair.setPublicKey(publicKeyString);
rsaKeyPair.setPrivateKey(privateKeyString);
return rsaKeyPair;
}
public static String encrypt(String str, String publicKey) throws Exception {
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);
return Base64.encodeBase64String(cipher.doFinal(str.getBytes(StandardCharsets.UTF_8)));
}
public static String decrypt(String str, String privateKey) throws Exception {
byte[] inputByte = Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8));
byte[] decoded = Base64.decodeBase64(privateKey);
PrivateKey priKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, priKey);
return new String(cipher.doFinal(inputByte));
}
public static String sign(String plainText, String privateKey) throws Exception {
Signature privateSignature = Signature.getInstance("SHA256withRSA");
privateSignature.initSign(getPrivate(privateKey));
privateSignature.update(plainText.getBytes("UTF-8"));
byte[] signature = privateSignature.sign();
return Base64.encodeBase64String(signature);
}
public static boolean verify(String plainText, String signature, String publicKey) throws Exception {
Signature publicSignature = Signature.getInstance("SHA256withRSA");
publicSignature.initVerify(getPublic(publicKey));
publicSignature.update(plainText.getBytes("UTF-8"));
byte[] signatureBytes = Base64.decodeBase64(signature);
return publicSignature.verify(signatureBytes);
}
}
@Test
public void testRsa() throws Exception {
RSAUtils.RSAKeyPair keyPair = RSAUtils.getKeyPair();
String realVal = "1234333333";
String encodeval = RSAUtils.encrypt("1234333333", keyPair.getPublicKey());
System.out.println("encodeVal:::" + encodeval);
String decodeval = RSAUtils.decrypt(encodeval, keyPair.getPrivateKey());
System.out.println("decodeval:::" + decodeval);
String deval = RSAUtils.decrypt(encodeval, keyPair.getPrivateKey());
System.out.println("deval:::"+deval);
boolean istrue = realVal.equals(deval);
System.out.println(istrue);
String abcdefghigklmn = RSAUtils.sign("abcdefghigklmn", keyPair.getPrivateKey());
System.out.println("sign:"+abcdefghigklmn);
boolean xxxxx = RSAUtils.verify("abcdefghigklmn", abcdefghigklmn, keyPair.getPublicKey());
System.out.println("is:"+xxxxx);
}
https://www.npmjs.com/package/jsencrypt
// Sign with the private key...
var sign = new JSEncrypt();
sign.setPrivateKey($('#privkey').val());
var signature = sign.sign($('#input').val(), CryptoJS.SHA256, "sha256");
// Verify with the public key...
var verify = new JSEncrypt();
verify.setPublicKey($('#pubkey').val());
var verified = verify.verify($('#input').val(), signature, CryptoJS.SHA256);
// Now a simple check to see if the round-trip worked.
if (verified) {
alert('It works!!!');
}
else {
alert('Something went wrong....');
}

浙公网安备 33010602011771号