前端加解密
JSEncrypt 实现非对称加密
Github 地址:JSEncrypt
首先这个包 需要提前生成 公钥 私钥 和 依赖 openssl
注意:
- 明文长度最大为公钥长度
-11
,假如我的公钥长度是128
,那明文最长也就117
- 这个库是与 openssl 一起工作,首先生成公钥私钥
openssl genrsa -out rsa_1024_priv.pem 1024
openssl rsa -pubout -in rsa_1024_priv.pem -out rsa_1024_pub.pem
前端JS加解密
<script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
<script src="bin/jsencrypt.min.js"></script>
<script type="text/javascript"> $(function () {
//被加密的信息var data = 'content';//公钥var pub_key = `-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCigl9qBi6/wNAZLbU/P+7t6AvIyHHHdiOmbbInHrv1ihRXFCpTQLHBg7MoImLGiS858i43T2sMSWnWfG5wfasLtblDPqodL7/O50Z5urICs3/WlbK/qeluHKVwhC3wfq+y1gdOQf+90GFOi3uyF03UhYSiyFlLpfTR13vwR8LBNwIDAQAB -----END PUBLIC KEY-----`;//私钥var private_key = `-----BEGIN PRIVATE KEY----- MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMvbPyPuExTOqhjouNe8Y6DzGIWwFVPxQRNAQ56NNBYy67nKmr2YB44UXz49AUTagbjikQyJHvmcL6tnJtNwEKc2yrrtag1NY25oENOoGIC+ts0iTTiuvus0IOGy6m6LxGrlN9SvW8nCw3m3L0XDZnx6XyTxBu8J0m0HUJTI5zUBAgMBAAECgYBFWlmox54GPijwQHxiKN1cLFfzY2xeGn2hJwPaNP+7bad0ldD/H3GyjIu6iNadrhjj5XCjayL2mIQ/M+Cpnj6LiLvmEIlSqRy6X4hV/DbesVWvfFv+QnFV53wo5oEwGS8BxED11lbEVY59B6UWpPCNrWVSOaQhtgt3A23bw9MwgQJBAPkJdVodDqx5A4f0RejFj8J4mFWToMaQdaqp1QrzkHoFH0pe8Gq2JGME32FAc5QIa4J8iLPUiSqK0G6gEC0Igv0CQQDRjmXbgX+/sbPxcOe2isF+cXOyahvUKWcyuu0HAqQU4W546+G0SjgzWJ00YajTtJBNjTCBR8L8+zjaxOtIkcNVAkB/+IFKPjZFIKZU3YxzEdpO14OILiVnA+LDQSRNzV1HpowuvlySqWhHTcCwC9uYjT8ZvX7N0gBuUQjMYAoP6hjNAkB7NdNztXdsOUqIqg7DSGAuPPx+qV7FZraToE5e8dGRqV4v4NjrDTxwDCkaNFV0bFTwFBSx3oSqA/fQwTlpiLKlAkEAhbyo9sJAbo2RFo3trIPCpufgAlgHl45aDimleZbko5nC100R7t6rUUs5itzjiY1Psn0yb6darH3dXx0o795Jlg== -----END PRIVATE KEY-----`;//new JSEncryptvar js_encrypt = new JSEncrypt();//初始化公钥js_encrypt.setPublicKey(pub_key);//初始化私钥js_encrypt.setPrivateKey(private_key);//通过 公钥 加密var encrypted = js_encrypt.encrypt(data);console.log(encrypted);//通过 私钥 解密var uncrypted = js_encrypt.decrypt(encrypted);console.log(uncrypted); }); </script>
后端PHP对应加解密
class Crypt
{
const PUBLIC_KEY = '-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCigl9qBi6/wNAZLbU/P+7t6AvIyHHHdiOmbbInHrv1ihRXFCpTQLHBg7MoImLGiS858i43T2sMSWnWfG5wfasLtblDPqodL7/O50Z5urICs3/WlbK/qeluHKVwhC3wfq+y1gdOQf+90GFOi3uyF03UhYSiyFlLpfTR13vwR8LBNwIDAQAB -----END PUBLIC KEY-----';const PRIVATE_KEY = '-----BEGIN PRIVATE KEY----- MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMvbPyPuExTOqhjouNe8Y6DzGIWwFVPxQRNAQ56NNBYy67nKmr2YB44UXz49AUTagbjikQyJHvmcL6tnJtNwEKc2yrrtag1NY25oENOoGIC+ts0iTTiuvus0IOGy6m6LxGrlN9SvW8nCw3m3L0XDZnx6XyTxBu8J0m0HUJTI5zUBAgMBAAECgYBFWlmox54GPijwQHxiKN1cLFfzY2xeGn2hJwPaNP+7bad0ldD/H3GyjIu6iNadrhjj5XCjayL2mIQ/M+Cpnj6LiLvmEIlSqRy6X4hV/DbesVWvfFv+QnFV53wo5oEwGS8BxED11lbEVY59B6UWpPCNrWVSOaQhtgt3A23bw9MwgQJBAPkJdVodDqx5A4f0RejFj8J4mFWToMaQdaqp1QrzkHoFH0pe8Gq2JGME32FAc5QIa4J8iLPUiSqK0G6gEC0Igv0CQQDRjmXbgX+/sbPxcOe2isF+cXOyahvUKWcyuu0HAqQU4W546+G0SjgzWJ00YajTtJBNjTCBR8L8+zjaxOtIkcNVAkB/+IFKPjZFIKZU3YxzEdpO14OILiVnA+LDQSRNzV1HpowuvlySqWhHTcCwC9uYjT8ZvX7N0gBuUQjMYAoP6hjNAkB7NdNztXdsOUqIqg7DSGAuPPx+qV7FZraToE5e8dGRqV4v4NjrDTxwDCkaNFV0bFTwFBSx3oSqA/fQwTlpiLKlAkEAhbyo9sJAbo2RFo3trIPCpufgAlgHl45aDimleZbko5nC100R7t6rUUs5itzjiY1Psn0yb6darH3dXx0o795Jlg== -----END PRIVATE KEY-----';public static function RSADecrypt($encryptString = ''){
$decrypted = '';$privateKey = self::PRIVATE_KEY;openssl_private_decrypt(base64_decode($encryptString), $decrypted, $privateKey);return $decrypted;}public static function RSAEncrypt($data = ''){
$encrypt_data = '';$publicKey = self::PUBLIC_KEY;openssl_public_encrypt($data, $encrypt_data, $publicKey);$encrypt_data = base64_encode($encrypt_data);return $encrypt_data;}
}$data = 'crypt';
echo Crypt::RSAEncrypt($data);
CryptoJS 实现 AES 对称加密
Github 地址:CryptoJs
注意
? 明文长度没有限制但是加密的文本也会随之变长
JS加解密
<script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
<script src="http://cdn.bootcss.com/crypto-js/3.1.9/crypto-js.js"></script>
<script> const AES_KEY = "XyA2LDcCF5V1nad0zl2mkGkUdbenn62x"; // 16位 对应 128-CBC; 32位对应256-CBC const AES_IV = "118zbeZMXHa0ZIYk"; //16位// 加密 function aes_encrypt(plainText, encode) {
var encrypted = CryptoJS.AES.encrypt(plainText, CryptoJS.enc.Utf8.parse(AES_KEY), {
iv: CryptoJS.enc.Utf8.parse(AES_IV),mode: CryptoJS.mod.CBC,padding: CryptoJS.pad.Pkcs7});// // hex 或 base64 编码return encode === void 0 ? encrypted.ciphertext.toString() : CryptoJS.enc.Base64.stringify(encrypted.ciphertext); }// 解密 function aes_decrypt(ciphertext) {
var decrypted = CryptoJS.AES.decrypt(CryptoJS.enc.Hex.parse(ciphertext), CryptoJS.enc.Utf8.parse(AES_KEY), {
iv: CryptoJS.enc.Utf8.parse(AES_IV),mode: CryptoJS.mod.CBC,padding: CryptoJS.pad.Pkcs7});return decrypted.toString(CryptoJS.enc.Utf8); }data = 'my message'; encrypt_data = aes_encrypt(data); console.log(encrypt_data); decrypt_data = aes_decrypt(encrypt_data); console.log(decrypt_data); </script>
后端PHP对应加解密
注意
mode
选择取决于 key
的长度,
key
是16
位的则使用AES-128-CBC
;key
是32
位的则使用AES-256-CBC
class Crypt
{
public static function ASEncrypt($data, $key, $iv, $mode = 'AES-256-CBC'){
$encrypted_data = openssl_encrypt($data, $mode, $key, OPENSSL_RAW_DATA, $iv);return bin2hex($encrypted_data);}public static function ASEDecrypt($data, $key, $iv, $mode = 'AES-256-CBC'){
return openssl_decrypt((hex2bin($data)), $mode, $key, OPENSSL_RAW_DATA, $iv);}
}
// 前后端 key iv 保持一致
$key = 'XyA2LDcCF5V1nad0zl2mkGkUdbenn62x';
$iv = '118zbeZMXHa0ZIYk';
$data = 'crypt';echo Crypt.ASEDecrypt(Crypt.ASEncrypt($data, $key, $iv), $key, $iv) === $data;
jsrsasign 实现 SHA1withRSA 签名
Github 地址:jsrsasign
前端 JS 生成签名
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsrsasign/8.0.20/jsrsasign-all-min.js"></script><script> var private_key = `-----BEGIN PRIVATE KEY----- MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMvbPyPuExTOqhjouNe8Y6DzGIWwFVPxQRNAQ56NNBYy67nKmr2YB44UXz49AUTagbjikQyJHvmcL6tnJtNwEKc2yrrtag1NY25oENOoGIC+ts0iTTiuvus0IOGy6m6LxGrlN9SvW8nCw3m3L0XDZnx6XyTxBu8J0m0HUJTI5zUBAgMBAAECgYBFWlmox54GPijwQHxiKN1cLFfzY2xeGn2hJwPaNP+7bad0ldD/H3GyjIu6iNadrhjj5XCjayL2mIQ/M+Cpnj6LiLvmEIlSqRy6X4hV/DbesVWvfFv+QnFV53wo5oEwGS8BxED11lbEVY59B6UWpPCNrWVSOaQhtgt3A23bw9MwgQJBAPkJdVodDqx5A4f0RejFj8J4mFWToMaQdaqp1QrzkHoFH0pe8Gq2JGME32FAc5QIa4J8iLPUiSqK0G6gEC0Igv0CQQDRjmXbgX+/sbPxcOe2isF+cXOyahvUKWcyuu0HAqQU4W546+G0SjgzWJ00YajTtJBNjTCBR8L8+zjaxOtIkcNVAkB/+IFKPjZFIKZU3YxzEdpO14OILiVnA+LDQSRNzV1HpowuvlySqWhHTcCwC9uYjT8ZvX7N0gBuUQjMYAoP6hjNAkB7NdNztXdsOUqIqg7DSGAuPPx+qV7FZraToE5e8dGRqV4v4NjrDTxwDCkaNFV0bFTwFBSx3oSqA/fQwTlpiLKlAkEAhbyo9sJAbo2RFo3trIPCpufgAlgHl45aDimleZbko5nC100R7t6rUUs5itzjiY1Psn0yb6darH3dXx0o795Jlg== -----END PRIVATE KEY-----`;var data = 'crypt';// 后端提供的是pck#8的密钥对,所以这里使用 KEYUTIL.getKey来解析密钥 var key = KEYUTIL.getKey(private_key); // 设定签名以 SHA1 为基准 var sig = new KJUR.crypto.Signature({
"alg": "SHA1withRSA"}); // 初始化 sig.init(rsa); // 传入待加密字符串 sig.updateString(data); // // 生成密文 var sign = hextob64(sig.sign()); console.log(sign);</script>
后端 PHP 对应加密
class SSLEncrypt
{
const PRIVATE_KEY = '-----BEGIN PRIVATE KEY----- MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMvbPyPuExTOqhjouNe8Y6DzGIWwFVPxQRNAQ56NNBYy67nKmr2YB44UXz49AUTagbjikQyJHvmcL6tnJtNwEKc2yrrtag1NY25oENOoGIC+ts0iTTiuvus0IOGy6m6LxGrlN9SvW8nCw3m3L0XDZnx6XyTxBu8J0m0HUJTI5zUBAgMBAAECgYBFWlmox54GPijwQHxiKN1cLFfzY2xeGn2hJwPaNP+7bad0ldD/H3GyjIu6iNadrhjj5XCjayL2mIQ/M+Cpnj6LiLvmEIlSqRy6X4hV/DbesVWvfFv+QnFV53wo5oEwGS8BxED11lbEVY59B6UWpPCNrWVSOaQhtgt3A23bw9MwgQJBAPkJdVodDqx5A4f0RejFj8J4mFWToMaQdaqp1QrzkHoFH0pe8Gq2JGME32FAc5QIa4J8iLPUiSqK0G6gEC0Igv0CQQDRjmXbgX+/sbPxcOe2isF+cXOyahvUKWcyuu0HAqQU4W546+G0SjgzWJ00YajTtJBNjTCBR8L8+zjaxOtIkcNVAkB/+IFKPjZFIKZU3YxzEdpO14OILiVnA+LDQSRNzV1HpowuvlySqWhHTcCwC9uYjT8ZvX7N0gBuUQjMYAoP6hjNAkB7NdNztXdsOUqIqg7DSGAuPPx+qV7FZraToE5e8dGRqV4v4NjrDTxwDCkaNFV0bFTwFBSx3oSqA/fQwTlpiLKlAkEAhbyo9sJAbo2RFo3trIPCpufgAlgHl45aDimleZbko5nC100R7t6rUUs5itzjiY1Psn0yb6darH3dXx0o795Jlg== -----END PRIVATE KEY-----';public static function SHA1withRSA($data, $code = ''){
$key = openssl_get_privatekey(static::PRIVATE_KEY);$signature = '';openssl_sign($data, $signature, $key);openssl_free_key($key);$sign = base64_encode($signature);return $sign;}}