当前位置: 首页 > news >正文

网站公司建设网站wordpress免备案cdn

网站公司建设网站,wordpress免备案cdn,济南网站建设优化熊掌号,上海网站建设的意义目录一、序言二、关于PKCS#1和PKCS#8格式密钥1、简介2、区别二、关于JSEncrypt三、关于jsrsasign四、前端RSA加解密、加验签示例1、相关依赖2、cryptoUtils工具类封装3、测试用例五、Java后端RSA加解密、加验签1、CryptoUtils工具类封装2、测试用例六、前后端加解密、加验签交互… 目录一、序言二、关于PKCS#1和PKCS#8格式密钥1、简介2、区别二、关于JSEncrypt三、关于jsrsasign四、前端RSA加解密、加验签示例1、相关依赖2、cryptoUtils工具类封装3、测试用例五、Java后端RSA加解密、加验签1、CryptoUtils工具类封装2、测试用例六、前后端加解密、加验签交互测试1、前端加密后端解密(1) 前端代码(2) 后端代码2、后端加密前端解密(1) 后端代码(2) 前端代码3、前端加签后端验签(1) 前端代码(2) 后端代码4、后端加签前端验签(1) 后端代码(2) 前端代码一、序言 最近有一些安全性要求比较高的场景我们提供API给第三方商户用于收单其中有几个功能是绑卡、ATM/POS密码变更。 出于合规和监管要求第三方商户不能保存卡号、CVV、密码等敏感信息所以相关的敏感操作必须在接口提供方H5页面中完成。为了最大程度保证安全性我们决定对敏感信息进行加密传输同时对请求参数进行加签处理。 由于前端并不需要解密操作最终我们选择RSA非对称加密前端这块主要采用jsencrypt进行加解密jsrsasign用来生成密钥对、加签验签。 二、关于PKCS#1和PKCS#8格式密钥 由于Java非对称加解密、加验签都是采用PKCS#8格式的密钥PKCS#1格式的密钥跑不通这里先简单介绍一下两者的区别。 1、简介 PKCS#1和PKCS#8是两个不同的数字证书标准。 PKCS#1是一个公钥加密标准它定义了使用RSA算法进行加密和签名的格式。主要用于对数字签名、加密以及数字签名验证等应用。 PKCS#8则是一个私钥保护标准它定义了私钥的存储格式。它主要用于在文件中对私钥进行保护以防止意外泄露或不当使用。 总的来说PKCS#1是针对公钥的标准而PKCS#8是针对私钥的标准。 2、区别 两者的密钥格式不一样下面以标准.pem格式为例看下PKCS#1格式和PKCS#8格式密钥的区别 PKCS#1格式私钥 -----BEGIN RSA PRIVATE KEY----- MIICXAIBAAKBgQC5BW6T9GVaaG/epGDjPpY3wN0DrBtNojvxkEgpUdOAxgAepqe ... TbzKH/LEqZN8WVau3bf41yAx2YoaOsIJJtOUTYcfh14 -----END RSA PRIVATE KEY-----PKCS#8格式私钥 -----BEGIN PRIVATE KEY----- MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALkFbpP0ZVpob96k ... wgkm05RNhxHXg -----END PRIVATE KEY-----PKCS#1格式公钥 -----BEGIN RSA PUBLIC KEY----- MIICXAIBAAKBgQC5BW6T9GVaaG/epGDjPpY3wN0DrBtNojvxkEgpUdOAxgAepqe ... TbzKH/LEqZN8WVau3bf41yAx2YoaOsIJJtOUTYcfh14 -----END RSA PUBLIC KEY-----PKCS#8格式公钥 -----BEGIN PUBLIC KEY----- MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALkFbpP0ZVpob96k ... wgkm05RNhxHXg -----END PUBLIC KEY-----二、关于JSEncrypt JSEncrypt是前端RSA加解密、密钥生成的一个实现方案API也比较简单更多请参考JSEncrypt官网。 官网有个线上的Demo可以生成非对称密钥还有加解密。 Home页有相关的使用示例还是很简单的。 // Create the encryption object and set the key. var crypt new JSEncrypt(); crypt.setKey(__YOUR_OPENSSL_PRIVATE_OR_PUBLIC_KEY__); //You can use also setPrivateKey and setPublicKey, they are both alias to setKey//Eventhough the methods are called setPublicKey and setPrivateKey, remember //that they are only alias to setKey, so you can pass them both a private or //a public openssl key, just remember that setting a public key allows you to only encrypt.var text test; // Encrypt the data with the public key. var enc crypt.encrypt(text); // Now decrypt the crypted text with the private key. var dec crypt.decrypt(enc);// Now a simple check to see if the round-trip worked. if (dec text){alert(It works!!!); } else {alert(Something went wrong....); }备注Download页有JSEncrypt官网demo的源代码。 三、关于jsrsasign jsrsasign是一个开源的纯JavaScript加密库支持RSA/RSAPSS/ECDSA/DSA签名和验签PKCS#1/5/8公私钥生成等等。 在Github上有两篇文章一篇是关于如何使用Signature类进行加签、验签的一篇是关于jsrsasign和Java互用性的里面有通过Java加签通过jsrsasign验签的demo。 更多相关类和方法的使用和描述可以参考jsrsasign API文档说明。 四、前端RSA加解密、加验签示例 1、相关依赖 // JSEncrypt npm i jsencrypt// jsrsasign npm i jsrsasign 2、cryptoUtils工具类封装 import CryptoJS from crypto-js; import JSEncrypt from jsencrypt; import JsRsaSign from jsrsasign;/*** RSA加密* param publicKey 公钥* param plainText 明文* returns {*} 密文*/ export function encryptByRSA(publicKey, plainText) {const encryptor new JSEncrypt();encryptor.setPublicKey(publicKey);return encryptor.encrypt(plainText); }/*** RSA解密* param privateKey 私钥* param cipherText 密文* returns {*} 明文*/ export function decryptByRSA(privateKey, cipherText) {const decrypter new JSEncrypt();decrypter.setPrivateKey(privateKey);return decrypter.decrypt(cipherText); }/*** 生成RSA密钥对填充模式为PKCS8。* 更多模式参考a hrefhttps://kjur.github.io/jsrsasign/api/symbols/KEYUTIL.htmlhttps://kjur.github.io/jsrsasign/api/symbols/KEYUTIL.html/a* returns {{privateKey: (string|string|*), publicKey: (string|string|*)}}*/ export function generateRsaKeyWithPKCS8() {const keyPair JsRsaSign.KEYUTIL.generateKeypair(RSA, 1024);const privateKey JsRsaSign.KEYUTIL.getPEM(keyPair.prvKeyObj, PKCS8PRV);const publicKey JsRsaSign.KEYUTIL.getPEM(keyPair.pubKeyObj);return { privateKey, publicKey }; }/*** SHA256和RSA加签* param privateKey 私钥* param msg 加签内容* returns {string} Base64编码签名内容*/ export function signBySHA256WithRSA(privateKey, msg) {const key JsRsaSign.KEYUTIL.getKey(privateKey);const signature new JsRsaSign.KJUR.crypto.Signature({alg: SHA256withRSA,});signature.init(key);signature.updateString(msg);// 签名后的为16进制字符串这里转换为16进制字符串return JsRsaSign.hextob64(signature.sign()); }/*** SHA256和RSA验签* param publicKey 公钥必须为标准pem格式。如果是PKCS1格式必须包含-----BEGIN RSA PRIVATE KEY-----如果是PKCS8格式必须包含-----BEGIN PRIVATE KEY-----* param base64SignStr Base64编码签名字符串* param msg 原内容* returns {boolean} 是否验签通过*/ export function verifyBySHA256WithRSA(publicKey, base64SignStr, msg) {const key JsRsaSign.KEYUTIL.getKey(publicKey);const signature new JsRsaSign.KJUR.crypto.Signature({alg: SHA256withRSA,});signature.init(key);signature.updateString(msg);// 需要将Base64进制签名字符串转换成16进制字符串return signature.verify(JsRsaSign.b64tohex(base64SignStr)); }3、测试用例 先在前端测试下密钥对生成RSA加解密、加验签测试代码如下 import * as CryptoUtils from /utils/cryptoUtils.js;const {privateKey, publicKey} CryptoUtils.generateRsaKeyWithPKCS8(); console.log(生成的私钥为\n${privateKey}); console.log(生成的公钥为\n${publicKey});const cipherText CryptoUtils.encryptByRSA(publicKey, test); console.log(test加密后的内容为\n${cipherText});const plainText CryptoUtils.decryptByRSA(privateKey, cipherText); console.log(解密后的内容为\n${plainText});const signature CryptoUtils.signBySHA256WithRSA(privateKey, test); console.log(生成的签名\n${signature});const isVerified CryptoUtils.verifyBySHA256WithRSA(publicKey, signature, test); console.log(是否验签通过${isVerified});控制台输出结果为 生成的私钥为 -----BEGIN PRIVATE KEY----- MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMv1adNmKNw4rtr2 Dy92DZ3Nk1SCrGGetlq0sSgLY8bJsByAvP2ZOOiiWq2xDUVu8ZpQfM8v89tjegfr sIUcN/ZVLc68Ric3BIto85oQc9jBzaCk1rXeNMePkSVqNaC/n4kJ73Y41ZgKAe0 GvyqMyUNhk8VZdQSNATSvlGep3AgMBAAECgYBoKMvDry98zHUZsb4iQSJK1xr U1SvgftEtXSnq7Fn6sZquABMTry2aXt/qqTJadAu653hvW5/Av1mICKEyBV3aT4O jQRGPMgp6WhXvQepUIuyi9qlfUVsJy/J0zGKZeKsCFlwZ2e2j4Un7Bb//pgUfjJ rbPtwC7U85oHjtJb6QJBAOdcm07ThSXFbicj2MuX9Gh7geMjncf6aqnrOwUFjO0d 5OxfYRAxrZD1GghygHyoJ4ZOHgJ0s6HVEYjg/u6DBdsCQQDhrb4IOVdSew2cW15f t/5DAKUXRRQBfz0OxOs0Uv5k7zqIYmysWVRGaZgj8oMZ7gYxN1eYNOKTwVjiuwb uyaVAkEA0OGSMpPT1WsvbVT26bFyb1Z6yTihvif/XxPKgFknh/kCcsoWFwnS1ne vBusl181BLVE0CL4aM9pogEghB3GwJAWJTVzmyTdfCOxxyAqg5yRrrsiKPI7dJ xA5PNA6PhBbSpwkrn1Q6LIcg4y4NZKkhfbdoHK9s2REDUHsrCgd/sQJAALEePCX hcHWnwbm4kRFyJCO4dWkii7o28ohTRourlNsoEmiu17lt7PY1C3D6A4FFCY/H pGM0i0lJue8rZA -----END PRIVATE KEY-----生成的公钥为 -----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDL9WnTZijcOK7a9g8vdg2dzZNU gqxhnrZatLEoC2PGybAcgLz9mTjoolqtsQ1FbvGaUHzPL/PbY3oH67CFHDf2VS3O vEYnNwSLaPOaEHPYwc/mgpNa13jTHj5ElajWgv5JCe92ONWYCgHtBr8qjMlDYZP FWXfkEjQE0r/pRnqdwIDAQAB -----END PUBLIC KEY-----test加密后的内容为 KjcaDKLnBbvxRzuKMysqoz9MHRXCUNIH67XDiFGTJbM8Rjw4Cei0CzjAPjk2jgAR37Kgh6lX2Xg8AI9wEmzWr08bt8i2FFxVMrcfOCs5zI1y2T7G9034f5b0gNx/Pc4dDz1k453vo0AhCC0vrtb1OfbsRu5oOFns0TqoAMY解密后的内容为test生成的签名 t0koTqhiWmq/wEvI/ieJq5kZj7Dc/limF7GNVtHNLReqLVBXZvAZrOIwdqda7LBHBSHcRZBISWtbuyDiOR9KFPObrOgOEUOdfACUMzjWKCtO8ZgcQU02FyGeeH2rT9rJEJAXDEMKn3H4ZdbrUFPY3jQRl535wnK9CLpxqAG4是否验签通过true备注为什么在前端生成PKCS#8格式密钥呢 因为在Java中非对称加解密、加验签都是用的PKCS#8PKCS#1格式密钥需要转换成PKCS#8。 五、Java后端RSA加解密、加验签 1、CryptoUtils工具类封装 import com.universe.crypto.CryptoUtils.Algorithm.Encryption; import com.universe.crypto.CryptoUtils.Algorithm.Signing; import lombok.AllArgsConstructor; import lombok.Data; import lombok.Getter; import lombok.NoArgsConstructor; import org.apache.commons.lang3.StringUtils;import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Base64; import java.util.Base64.Decoder; import java.util.Base64.Encoder; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap;/*** 支持AES、DES、RSA加密、数字签名以及生成对称密钥和非对称密钥对*/ public class CryptoUtils {private static final Charset DEFAULT_CHARSET StandardCharsets.UTF_8;private static final Encoder BASE64_ENCODER Base64.getEncoder();private static final Decoder BASE64_DECODER Base64.getDecoder();private static final MapAlgorithm, KeyFactory KEY_FACTORY_CACHE new ConcurrentHashMap();private static final MapAlgorithm, Cipher CIPHER_CACHE new HashMap();/*** 生成对称密钥目前支持的算法有AES、DES* param algorithm* return* throws NoSuchAlgorithmException*/public static String generateSymmetricKey(Algorithm algorithm) throws NoSuchAlgorithmException {KeyGenerator generator KeyGenerator.getInstance(algorithm.getName());generator.init(algorithm.getKeySize());SecretKey secretKey generator.generateKey();return BASE64_ENCODER.encodeToString(secretKey.getEncoded());}/*** 生成非对称密钥对目前支持的算法有RSA、DSA。备注默认生成的密钥格式为PKCS8* param algorithm* return* throws NoSuchAlgorithmException*/public static AsymmetricKeyPair generateAsymmetricKeyPair(Algorithm algorithm) throws NoSuchAlgorithmException {KeyPairGenerator generator KeyPairGenerator.getInstance(algorithm.getName());generator.initialize(algorithm.getKeySize());KeyPair keyPair generator.generateKeyPair();String publicKey BASE64_ENCODER.encodeToString(keyPair.getPublic().getEncoded());String privateKey BASE64_ENCODER.encodeToString(keyPair.getPrivate().getEncoded());return new AsymmetricKeyPair(publicKey, privateKey);}public static String encryptByRSA(String publicKeyText, String plainText) throws Exception {return encryptAsymmetrically(publicKeyText, plainText, Encryption.RSA_ECB_PKCS1);}public static String decryptByRSA(String privateKeyText, String ciphertext) throws Exception {return decryptAsymmetrically(privateKeyText, ciphertext, Encryption.RSA_ECB_PKCS1);}/*** SHA1签名算法和DSA加密算法结合使用生成数字签名* param privateKeyText* param msg* return 数字签名* throws Exception*/public static String signBySHA1WithDSA(String privateKeyText, String msg) throws Exception {return doSign(privateKeyText, msg, Encryption.DSA, Signing.SHA1WithDSA);}/*** SHA1签名算法和RSA加密算法结合使用生成数字签名* param privateKeyText 私钥* param msg 待加签内容* return 数字签名* throws Exception*/public static String signBySHA1WithRSA(String privateKeyText, String msg) throws Exception {return doSign(privateKeyText, msg, Encryption.RSA_ECB_PKCS1, Signing.SHA1WithRSA);}/*** SHA256签名算法和RSA加密算法结合使用生成数字签名* param privateKeyText 私钥* param msg 待加签内容* return 数字签名* throws Exception*/public static String signBySHA256WithRSA(String privateKeyText, String msg) throws Exception {return doSign(privateKeyText, msg, Encryption.RSA_ECB_PKCS1, Signing.SHA256WithRSA);}/*** SHA1签名算法和DSA加密算法检验数字签名* param publicKeyText 公钥* param msg 待验签内容* param signatureText 数字* return 检验是否成功* throws Exception*/public static boolean verifyBySHA1WithDSA(String publicKeyText, String msg, String signatureText) throws Exception {return doVerify(publicKeyText, msg, signatureText, Encryption.DSA, Signing.SHA1WithDSA);}/*** SHA1签名算法和RSA加密算法检验数字签名* param publicKeyText 公钥* param msg 待验签内容* param signatureText 签名* return 校验是否成功* throws Exception*/public static boolean verifyBySHA1WithRSA(String publicKeyText, String msg, String signatureText) throws Exception {return doVerify(publicKeyText, msg, signatureText, Encryption.RSA_ECB_PKCS1, Signing.SHA1WithRSA);}/*** SHA256签名算法和RSA加密算法检验数字签名* param publicKeyText 公钥* param msg 待验签内容* param signatureText 签名* return 校验是否成功* throws Exception*/public static boolean verifyBySHA256WithRSA(String publicKeyText, String msg, String signatureText) throws Exception {return doVerify(publicKeyText, msg, signatureText, Encryption.RSA_ECB_PKCS1, Signing.SHA256WithRSA);}/*** 对称加密* param secretKey 密钥* param iv 加密向量只有CBC模式才支持如果是CBC则必传* param plainText 明文* param algorithm 对称加密算法如AES、DES* return* throws Exception*/public static String encryptSymmetrically(String secretKey, String iv, String plainText, Algorithm algorithm) throws Exception {SecretKey key decodeSymmetricKey(secretKey, algorithm);IvParameterSpec ivParameterSpec StringUtils.isBlank(iv) ? null : decodeIv(iv);byte[] plainTextInBytes plainText.getBytes(DEFAULT_CHARSET);byte[] ciphertextInBytes transform(algorithm, Cipher.ENCRYPT_MODE, key, ivParameterSpec, plainTextInBytes);return BASE64_ENCODER.encodeToString(ciphertextInBytes);}/*** 对称解密* param secretKey 密钥* param iv 加密向量只有CBC模式才支持如果是CBC则必传* param ciphertext 密文* param algorithm 对称加密算法如AES、DES* return* throws Exception*/public static String decryptSymmetrically(String secretKey, String iv, String ciphertext, Algorithm algorithm) throws Exception {SecretKey key decodeSymmetricKey(secretKey, algorithm);IvParameterSpec ivParameterSpec StringUtils.isBlank(iv) ? null : decodeIv(iv);byte[] ciphertextInBytes BASE64_DECODER.decode(ciphertext);byte[] plainTextInBytes transform(algorithm, Cipher.DECRYPT_MODE, key, ivParameterSpec, ciphertextInBytes);return new String(plainTextInBytes, DEFAULT_CHARSET);}/*** 非对称加密* param publicKeyText 公钥* param plainText 明文* param algorithm 非对称加密算法* return* throws Exception*/public static String encryptAsymmetrically(String publicKeyText, String plainText, Algorithm algorithm) throws Exception {PublicKey publicKey regeneratePublicKey(publicKeyText, algorithm);byte[] plainTextInBytes plainText.getBytes(DEFAULT_CHARSET);byte[] ciphertextInBytes transform(algorithm, Cipher.ENCRYPT_MODE, publicKey, plainTextInBytes);return BASE64_ENCODER.encodeToString(ciphertextInBytes);}/*** 非对称解密* param privateKeyText 私钥* param ciphertext 密文* param algorithm 非对称加密算法* return* throws Exception*/public static String decryptAsymmetrically(String privateKeyText, String ciphertext, Algorithm algorithm) throws Exception {PrivateKey privateKey regeneratePrivateKey(privateKeyText, algorithm);byte[] ciphertextInBytes BASE64_DECODER.decode(ciphertext);byte[] plainTextInBytes transform(algorithm, Cipher.DECRYPT_MODE, privateKey, ciphertextInBytes);return new String(plainTextInBytes, DEFAULT_CHARSET);}/*** 生成数字签名* param privateKeyText 私钥* param msg 传输的数据* param encryptionAlgorithm 加密算法见Algorithm中的加密算法* param signatureAlgorithm 签名算法见Algorithm中的签名算法* return 数字签名* throws Exception*/public static String doSign(String privateKeyText, String msg, Algorithm encryptionAlgorithm, Algorithm signatureAlgorithm)throws Exception {PrivateKey privateKey regeneratePrivateKey(privateKeyText, encryptionAlgorithm);// Signature只支持签名算法Signature signature Signature.getInstance(signatureAlgorithm.getName());signature.initSign(privateKey);signature.update(msg.getBytes(DEFAULT_CHARSET));byte[] signatureInBytes signature.sign();return BASE64_ENCODER.encodeToString(signatureInBytes);}/*** 数字签名验证* param publicKeyText 公钥* param msg 传输的数据* param signatureText 数字签名* param encryptionAlgorithm 加密算法见Algorithm中的加密算法* param signatureAlgorithm 签名算法见Algorithm中的签名算法* return 校验是否成功* throws Exception*/public static boolean doVerify(String publicKeyText, String msg, String signatureText, Algorithm encryptionAlgorithm,Algorithm signatureAlgorithm) throws Exception {PublicKey publicKey regeneratePublicKey(publicKeyText, encryptionAlgorithm);Signature signature Signature.getInstance(signatureAlgorithm.getName());signature.initVerify(publicKey);signature.update(msg.getBytes(DEFAULT_CHARSET));return signature.verify(BASE64_DECODER.decode(signatureText));}/*** 将密钥进行Base64位解码重新生成SecretKey实例* param secretKey 密钥* param algorithm 算法* return*/private static SecretKey decodeSymmetricKey(String secretKey, Algorithm algorithm) {byte[] key BASE64_DECODER.decode(secretKey);return new SecretKeySpec(key, algorithm.getName());}private static IvParameterSpec decodeIv(String iv) {byte[] ivInBytes BASE64_DECODER.decode(iv);return new IvParameterSpec(ivInBytes);}private static PublicKey regeneratePublicKey(String publicKeyText, Algorithm algorithm)throws NoSuchAlgorithmException, InvalidKeySpecException {byte[] keyInBytes BASE64_DECODER.decode(publicKeyText);KeyFactory keyFactory getKeyFactory(algorithm);// 公钥必须使用RSAPublicKeySpec或者X509EncodedKeySpecKeySpec publicKeySpec new X509EncodedKeySpec(keyInBytes);PublicKey publicKey keyFactory.generatePublic(publicKeySpec);return publicKey;}private static PrivateKey regeneratePrivateKey(String key, Algorithm algorithm) throws Exception {byte[] keyInBytes BASE64_DECODER.decode(key);KeyFactory keyFactory getKeyFactory(algorithm);// 私钥必须使用RSAPrivateCrtKeySpec或者PKCS8EncodedKeySpecKeySpec privateKeySpec new PKCS8EncodedKeySpec(keyInBytes);PrivateKey privateKey keyFactory.generatePrivate(privateKeySpec);return privateKey;}private static KeyFactory getKeyFactory(Algorithm algorithm) throws NoSuchAlgorithmException {KeyFactory keyFactory KEY_FACTORY_CACHE.get(algorithm);if (keyFactory null) {keyFactory KeyFactory.getInstance(algorithm.getName());KEY_FACTORY_CACHE.put(algorithm, keyFactory);}return keyFactory;}private static byte[] transform(Algorithm algorithm, int mode, Key key, byte[] msg) throws Exception {return transform(algorithm, mode, key, null, msg);}private static byte[] transform(Algorithm algorithm, int mode, Key key, IvParameterSpec iv, byte[] msg) throws Exception {Cipher cipher CIPHER_CACHE.get(algorithm);// double check减少上下文切换if (cipher null) {synchronized (CryptoUtils.class) {if ((cipher CIPHER_CACHE.get(algorithm)) null) {cipher determineWhichCipherToUse(algorithm);CIPHER_CACHE.put(algorithm, cipher);}cipher.init(mode, key, iv);return cipher.doFinal(msg);}}synchronized (CryptoUtils.class) {cipher.init(mode, key, iv);return cipher.doFinal(msg);}}private static Cipher determineWhichCipherToUse(Algorithm algorithm) throws NoSuchAlgorithmException, NoSuchPaddingException {Cipher cipher;String transformation algorithm.getTransformation();// 官方推荐的transformation使用algorithm/mode/padding组合SunJCE使用ECB作为默认模式使用PKCS5Padding作为默认填充if (StringUtils.isNotEmpty(transformation)) {cipher Cipher.getInstance(transformation);} else {cipher Cipher.getInstance(algorithm.getName());}return cipher;}/*** 算法分为加密算法和签名算法更多算法实现见br/* a hrefhttps://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#impljdk8中的标准算法/a*/public static class Algorithm {public interface Encryption {Algorithm AES_ECB_PKCS5 new Algorithm(AES, AES/ECB/PKCS5Padding, 128);Algorithm AES_CBC_PKCS5 new Algorithm(AES, AES/CBC/PKCS5Padding, 128);Algorithm DES_ECB_PKCS5 new Algorithm(DES, DES/ECB/PKCS5Padding, 56);Algorithm DES_CBC_PKCS5 new Algorithm(DES, DES/CBC/PKCS5Padding, 56);Algorithm RSA_ECB_PKCS1 new Algorithm(RSA, RSA/ECB/PKCS1Padding, 1024);Algorithm DSA new Algorithm(DSA, 1024);}public interface Signing {Algorithm SHA1WithDSA new Algorithm(SHA1withDSA, 1024);Algorithm SHA1WithRSA new Algorithm(SHA1WithRSA, 2048);Algorithm SHA256WithRSA new Algorithm(SHA256WithRSA, 2048);}Getterprivate String name;Getterprivate String transformation;Getterprivate int keySize;public Algorithm(String name, int keySize) {this(name, null, keySize);}public Algorithm(String name, String transformation, int keySize) {this.name name;this.transformation transformation;this.keySize keySize;}}DataNoArgsConstructorAllArgsConstructorpublic static class AsymmetricKeyPair {private String publicKey;private String privateKey;}}2、测试用例 AsymmetricKeyPair keyPair CryptoUtils.generateAsymmetricKeyPair(Encryption.RSA_ECB_PKCS1); String privateKey keyPair.getPrivateKey(); String publicKey keyPair.getPublicKey(); System.out.println(生成的私钥为\n privateKey); System.out.println(生成的公钥为\n publicKey);String cipherText CryptoUtils.encryptByRSA(publicKey, test); String plainText CryptoUtils.decryptByRSA(privateKey, cipherText); System.out.println(test加密后的密文为\n cipherText); System.out.println(解密后的明文为 plainText);String signature CryptoUtils.signBySHA256WithRSA(privateKey, message); boolean isVerified CryptoUtils.verifyBySHA256WithRSA(publicKey, message, signature); System.out.println(message加签后的签名为 signature); System.out.println(验签是否通过 isVerified);控制台输出如下 生成的私钥为 MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAL4TdBqlxJByJURSqNzthP18t2Q6tzmdwfoTJka0yy/DjEL1/mBPdcygwWBfVYLBvwuBUOyG4pbf/de0pmgc9b7SwNqqpHtmLxaEqW3ebovm0R2UFom0OS/5X5pdWNKuKDTCpP2xC1JSfRqS7WNgFEhCK7hRWBzIpifXvLzZNtAgMBAAECgYAcjOd/qS6hU8PtQ01CAhtbyAPz9i3XZa7hVUcGj9mFTyYeWLzg0o6rMepaA3fgsCF2JPJ21LvsVbDXWbc1JER1LYIWYZ79XnYZQgezmfqeSFxCJkndRZ/qXGnf/1EUJFjEafbkXGRvnv05B4QHBQGn3gfIa2xsLw2r3Yf8M5/gQJBAOXgqeH5yyJ6iNIw5S8EAR7VAUMPteQ/JqQ6lwYcesj/prqhwRX4x2m/wKh6qM2zZcFLMujYTyJsIQkzmOkFXkCQQDTrO1bnO84dbEVOUv73g0J1jg/3EIbt8uh7T4Iu82/9ycUyQ5D8oANh53rfPf5DXycXWXRlu2gwGvsyNRW1LSVAkEAnYs6go/Cgw9g2hVOcKhzfKnmcFDpHkPT5CEnB8ou8GAdcVz4SsmkSTpMnGrsE4X2nGcs23D1lCK15aQHms6QJBAJ/8GmXcph25Lj9JT/msaZReuaLimYCTmK/pPLKjJy4I4hveng6S8V/IeX4rtMwimTAXp1bgny2EpwjagG6wEUCQH9ap3J9fh8UicEPD1LO/GUTTNXuPiwWOcNgetntrjPAJx5b0bf6hEJOyEHtIsuSuzAD8G41o2tpsefact3EwzY生成的公钥为 MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCE3QapcSQciVEUqjc7YT9fLdkOrc5ncH6EyZGtMsvw4xC9f5gT3XMoMFgX1WCwb8LgVDshuKW3/3XtKZoHPW/ksDaqqR7Zi8WhKlt3m6L5tEdlBaJtDkvVaXVjSrig0wqT9sQtSUn0akvu1jYBRIQiu4UVgcyKYn17y82TbQIDAQABtest加密后的密文为 EA19/wkHbdXTc8sfLFhmnp/MWW3PLx2LeYFHWFNdhvY38Zoa4Ci8HJw8okkxzTfsSkgsiybMaz82rwF9lfcuEWzjbuGeVOvdkI0p/CvPDfikMYwOsxA7OqBJ/Hktn25l/ryEv7TxYlMFQ48jB0KPw/0Ivec9qfX2pgnyBl7WM解密后的明文为testmessage加签后的签名为 AByFyRoc/321db16voe9NQaicwkscTOGjBZGefWzB7dMadWXBtUPIK3CUXADLiiesehgAAcDbl06qVzx/6xeWPCK2ucCfn9dFybZfmAIsn3TATuDQIFvz/m2cHQAuH9fkmiGgMPOVY/VcILwri3RETuQwz4YSmP89o1cFqk验签是否通过true六、前后端加解密、加验签交互测试 1、前端加密后端解密 这里我们用前端生成的密钥对做测试。 (1) 前端代码 import * as CryptoUtils from /utils/cryptoUtils.js;const {privateKey, publicKey} CryptoUtils.generateRsaKeyWithPKCS8(); console.log(生成的私钥为\n${privateKey}); console.log(生成的公钥为\n${publicKey});const cipherText CryptoUtils.encryptByRSA(publicKey, test); console.log(test加密后的内容为\n${cipherText});控制台输出 生成的私钥为 -----BEGIN PRIVATE KEY----- MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMv1adNmKNw4rtr2 Dy92DZ3Nk1SCrGGetlq0sSgLY8bJsByAvP2ZOOiiWq2xDUVu8ZpQfM8v89tjegfr sIUcN/ZVLc68Ric3BIto85oQc9jBzaCk1rXeNMePkSVqNaC/n4kJ73Y41ZgKAe0 GvyqMyUNhk8VZdQSNATSvlGep3AgMBAAECgYBoKMvDry98zHUZsb4iQSJK1xr U1SvgftEtXSnq7Fn6sZquABMTry2aXt/qqTJadAu653hvW5/Av1mICKEyBV3aT4O jQRGPMgp6WhXvQepUIuyi9qlfUVsJy/J0zGKZeKsCFlwZ2e2j4Un7Bb//pgUfjJ rbPtwC7U85oHjtJb6QJBAOdcm07ThSXFbicj2MuX9Gh7geMjncf6aqnrOwUFjO0d 5OxfYRAxrZD1GghygHyoJ4ZOHgJ0s6HVEYjg/u6DBdsCQQDhrb4IOVdSew2cW15f t/5DAKUXRRQBfz0OxOs0Uv5k7zqIYmysWVRGaZgj8oMZ7gYxN1eYNOKTwVjiuwb uyaVAkEA0OGSMpPT1WsvbVT26bFyb1Z6yTihvif/XxPKgFknh/kCcsoWFwnS1ne vBusl181BLVE0CL4aM9pogEghB3GwJAWJTVzmyTdfCOxxyAqg5yRrrsiKPI7dJ xA5PNA6PhBbSpwkrn1Q6LIcg4y4NZKkhfbdoHK9s2REDUHsrCgd/sQJAALEePCX hcHWnwbm4kRFyJCO4dWkii7o28ohTRourlNsoEmiu17lt7PY1C3D6A4FFCY/H pGM0i0lJue8rZA -----END PRIVATE KEY-----生成的公钥为 -----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDL9WnTZijcOK7a9g8vdg2dzZNU gqxhnrZatLEoC2PGybAcgLz9mTjoolqtsQ1FbvGaUHzPL/PbY3oH67CFHDf2VS3O vEYnNwSLaPOaEHPYwc/mgpNa13jTHj5ElajWgv5JCe92ONWYCgHtBr8qjMlDYZP FWXfkEjQE0r/pRnqdwIDAQAB -----END PUBLIC KEY-----test加密后的内容为 KjcaDKLnBbvxRzuKMysqoz9MHRXCUNIH67XDiFGTJbM8Rjw4Cei0CzjAPjk2jgAR37Kgh6lX2Xg8AI9wEmzWr08bt8i2FFxVMrcfOCs5zI1y2T7G9034f5b0gNx/Pc4dDz1k453vo0AhCC0vrtb1OfbsRu5oOFns0TqoAMY解密后的内容为test (2) 后端代码 String privateKey MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMv1adNmKNw4rtr2Dy92DZ3Nk1SCrGGetlq0sSgLY8bJsByAvP2ZOOiiWq2xDUVu8ZpQfM8v89tjegfrsIUcN/ZVLc68Ric3BIto85oQc9jBzaCk1rXeNMePkSVqNaC/n4kJ73Y41ZgKAe0GvyqMyUNhk8VZdQSNATSvlGep3AgMBAAECgYBoKMvDry98zHUZsb4iQSJK1xrU1SvgftEtXSnq7Fn6sZquABMTry2aXt/qqTJadAu653hvW5/Av1mICKEyBV3aT4OjQRGPMgp6WhXvQepUIuyi9qlfUVsJy/J0zGKZeKsCFlwZ2e2j4Un7Bb//pgUfjJrbPtwC7U85oHjtJb6QJBAOdcm07ThSXFbicj2MuX9Gh7geMjncf6aqnrOwUFjO0d5OxfYRAxrZD1GghygHyoJ4ZOHgJ0s6HVEYjg/u6DBdsCQQDhrb4IOVdSew2cW15ft/5DAKUXRRQBfz0OxOs0Uv5k7zqIYmysWVRGaZgj8oMZ7gYxN1eYNOKTwVjiuwbuyaVAkEA0OGSMpPT1WsvbVT26bFyb1Z6yTihvif/XxPKgFknh/kCcsoWFwnS1nevBusl181BLVE0CL4aM9pogEghB3GwJAWJTVzmyTdfCOxxyAqg5yRrrsiKPI7dJxA5PNA6PhBbSpwkrn1Q6LIcg4y4NZKkhfbdoHK9s2REDUHsrCgd/sQJAALEePCXhcHWnwbm4kRFyJCO4dWkii7o28ohTRourlNsoEmiu17lt7PY1C3D6A4FFCY/HpGM0i0lJue8rZA; String cipherText KjcaDKLnBbvxRzuKMysqoz9MHRXCUNIH67XDiFGTJbM8Rjw4Cei0CzjAPjk2jgAR37Kgh6lX2Xg8AI9wEmzWr08bt8i2FFxVMrcfOCs5zI1y2T7G9034f5b0gNx/Pc4dDz1k453vo0AhCC0vrtb1OfbsRu5oOFns0TqoAMY;// 解密后的明文应该为test String plainText CryptoUtils.decryptByRSA(privateKey, cipherText); System.out.println(解密后的明文为 plainText);控制台输出如下 解密后的明文为test备注 从前端复制过来的密钥需要去掉-----BEGIN PRIVATE KEY-----前缀。从前端复制过来的密钥带有换行记得去掉中间的换行符。 2、后端加密前端解密 这里我们用后端生成的密钥对做测试。 (1) 后端代码 AsymmetricKeyPair keyPair CryptoUtils.generateAsymmetricKeyPair(Encryption.RSA_ECB_PKCS1); String privateKey keyPair.getPrivateKey(); String publicKey keyPair.getPublicKey(); System.out.println(生成的私钥为\n privateKey); System.out.println(生成的公钥为\n publicKey);String cipherText CryptoUtils.encryptByRSA(publicKey, test); System.out.println(test加密后的内容为\n cipherText);控制台输出为 生成的私钥为 MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJPh8WiDo3dhKHW9w86D4DX84pHAG03PIeOHCSezbyKeyKsuHA3qayGJ7JqQgWis557uawz95/EbBzzwmO0oyl16fkiRXcRppU/UbW6PUBbIpJNqCjnKcwDA5UXVDmIv0xXOP34jlnkY1DxnimqMAkgut8gncgdFxO0ap0us6lAgMBAAECgYBzlVpQ/OqMCRVNiYd8ZxicOc6Aaq0skKOFKWsfa6CGZ6KiIMTun3UiXqHeYOm0fcf/MYvcOKvLh/uNRuPQIV3WKAWJ6rdXQLjzmrH4QDMcmkMn0OKxxbe56MASPWka7/08GLiE1FJLDo8DEkBQnlDHqnt4e7BoZSgYVhWv52AQJBAMcr0O7xiB/Ge9aQzqYQJvdQ4JI53pM0lEx5HPzQjbrMjC1flb572js1ajKckkuTXnxzyTzC3JtfvGCcMqaaoECQQCE9LoSfZZHpVFCx4ZIh2VgzrGYnelktb6MenILhdji2j9i6ZyAqyg8TjLW9/kAKnaNAV2j6GF8/bOTX0UGolAkAcUWiFcKXwDqJw4WngRojvkYPxFaXC3TCYr3yXByqoIaVtO9vgCFZpTQ2V4bjLqoYo8XK89G17ai08Bf28BAkABGvRHKjDJSZg86KrYqUybjHUHraZEFMSKQz1IozBDvB/oXv6QQMgM/RrIQSPI2aqRpl2N9IkoEpSZdVD1KT9AkBtoz4Eg3Nuy1XdCCrTqTMioY0hP74xCcgURpooxmL2xhNUYu6PJrg4lkaiq8e/2Cr0ZQlps/pEDgaPdHDf3Et 生成的公钥为 MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCT4fFog6N3YSh1vcPOgA1/OKRwBtNzyHjhwkns28insirLhwN6mshieyakIForOee7msM/efxGwc88JjtKMvpden5IkV3EaaVP1G1uj1AWyKSTago5ynMPgwOVF1Q5iL9MVzj9I5Z5GNQ8Z4pqjAJILrfIJ3IHRcTtGqdLrOpQIDAQAB test加密后的内容为 RgJxGVSizKgfLnXjsqzTl9h0cUzm460EyHhdL3/qZLNbd6IVcU1AmOOsbFd9W8GtNhJiCERybgjCucr4c3/EQLXtF8vNHVMFp9ycDW4T8FMmFQn0f/oJ7/i9uEoNd9W8nWJcSRHuTw1rl4Mc7KnmwvdaTV2ZLOxBG6oAK8 (2) 前端代码 const privateKey MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJPh8WiDo3dhKHW9w86D4DX84pHAG03PIeOHCSezbyKeyKsuHA3qayGJ7JqQgWis557uawz95/EbBzzwmO0oyl16fkiRXcRppU/UbW6PUBbIpJNqCjnKcwDA5UXVDmIv0xXOP34jlnkY1DxnimqMAkgut8gncgdFxO0ap0us6lAgMBAAECgYBzlVpQ/OqMCRVNiYd8ZxicOc6Aaq0skKOFKWsfa6CGZ6KiIMTun3UiXqHeYOm0fcf/MYvcOKvLh/uNRuPQIV3WKAWJ6rdXQLjzmrH4QDMcmkMn0OKxxbe56MASPWka7/08GLiE1FJLDo8DEkBQnlDHqnt4e7BoZSgYVhWv52AQJBAMcr0O7xiB/Ge9aQzqYQJvdQ4JI53pM0lEx5HPzQjbrMjC1flb572js1ajKckkuTXnxzyTzC3JtfvGCcMqaaoECQQCE9LoSfZZHpVFCx4ZIh2VgzrGYnelktb6MenILhdji2j9i6ZyAqyg8TjLW9/kAKnaNAV2j6GF8/bOTX0UGolAkAcUWiFcKXwDqJw4WngRojvkYPxFaXC3TCYr3yXByqoIaVtO9vgCFZpTQ2V4bjLqoYo8XK89G17ai08Bf28BAkABGvRHKjDJSZg86KrYqUybjHUHraZEFMSKQz1IozBDvB/oXv6QQMgM/RrIQSPI2aqRpl2N9IkoEpSZdVD1KT9AkBtoz4Eg3Nuy1XdCCrTqTMioY0hP74xCcgURpooxmL2xhNUYu6PJrg4lkaiq8e/2Cr0ZQlps/pEDgaPdHDf3Et; const cipherText RgJxGVSizKgfLnXjsqzTl9h0cUzm460EyHhdL3/qZLNbd6IVcU1AmOOsbFd9W8GtNhJiCERybgjCucr4c3/EQLXtF8vNHVMFp9ycDW4T8FMmFQn0f/oJ7/i9uEoNd9W8nWJcSRHuTw1rl4Mc7KnmwvdaTV2ZLOxBG6oAK8; const plainText CryptoUtils.decryptByRSA(privateKey, cipherText); console.log(解密后的内容为${plainText});控制台输出 解密后的内容为test3、前端加签后端验签 这里我们用前端生成的密钥对做测试。 (1) 前端代码 const {privateKey, publicKey} CryptoUtils.generateRsaKeyWithPKCS8(); console.log(生成的私钥为\n${privateKey}); console.log(生成的公钥为\n${publicKey});const signature CryptoUtils.signBySHA256WithRSA(privateKey, test); console.log(生成的签名\n${signature});控制台输出如下 生成的私钥为 -----BEGIN PRIVATE KEY----- MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBALxzJU/N/lEAZO zMbzx5WrWDu31oKlHjth54APGHYCmqvi0dUeuSbv238tkem95GTy1kQRz9CMB WvvVdNYC78E8maBaMKbGZKVIScZ6eo8gkXxEoB7a3/y6a8L/SpQGgaI78JsnVGJ ijfGaGtfbldIQMxIc6gbNZOM/PAgMBAAECgYEAiAKE1Mwf1eSVLdhJq33e2oHs eH1u7kmci9LYan0qESgqScWAuCdmTenYhbTUKLPIOhQoxsw0cgZOOcWMqR2SSHW/ CK0Ql/5jP94wyX5Gw62jFXpLTVKQ1piiNjoujTKOsnkdtfh/JnjdeWh7GEcHhGGw yin0F1aHZgex4MkG0EECQQDsqJJxESC5QjZl5f6EDIbkSznmeV0IPfgIs8uN1QID jFbS97QhClSrsev4LXxuGkltOpWbJUkGnmjZhDPnV1nAkEAy9nzQndYxiv/XLpd Id2pBSBRs/panFFEIoEEb4UoY7QPLfQ6ZOQQ9vC5r1tWQtIhwiEjhYaGhnBZ1 TASRWQJBAOADNRMnxlT2Uu2jhobSIMFqX7VEvgY2Ollqb0yjC1P2fJ0X8X6w7LG KPnzfGvwH/7vzHteEME1SPydeV48tBMCQQCtCsZElar2DkMnI8zBO7yqdWIuk4Lj zclNRqpNpV0B00dPaxJmsnL1AVzhIcvA2qMmfUSImJpvrY1PedIAOBAkAvjVU0 3USMjvv5iudWyqqRy8Q9s2qeWYEivbFeLExiqGj9kmOkIfPcm96ElZr1F7PlaQb wj2AD2oaQGcQqUm -----END PRIVATE KEY-----生成的公钥为 -----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8cyflPzf5RPgGTszG88fuVq1g 7t9aCpR/o7YeeADxh2Pgpqr4tHVHrkm79t/LZHpveRk8tZEEc/QjAVr71XTWAu/B PJmgWjCm/hmSlSEnGenqPIJF8RKAe2t/8umvC/0qUBoGiO/CbJ1RiYo3/hmhrX25 fnSEDMSHOoGzWTjPzwIDAQAB -----END PUBLIC KEY-----生成的签名 Q9Mtq3gxi2YJ07FQtbry5zxGljomzKQNewhj10Ba10b3roAAdQUzqdQyP7rqARdPQgt0ClDgvtaL2TNYLc4URh7E3Kgx8T6pSFlPnU/b3cfCoVRPrr/gJBrsCkbNMITNXpVQpwIYe3P1zOrCUHuaQR82yCVUz3y43oOiE6qIY(2) 后端代码 String publicKey MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8cyflPzf5RPgGTszG88fuVq1g7t9aCpR/o7YeeADxh2Pgpqr4tHVHrkm79t/LZHpveRk8tZEEc/QjAVr71XTWAu/BPJmgWjCm/hmSlSEnGenqPIJF8RKAe2t/8umvC/0qUBoGiO/CbJ1RiYo3/hmhrX25fnSEDMSHOoGzWTjPzwIDAQAB; String signature Q9Mtq3gxi2YJ07FQtbry5zxGljomzKQNewhj10Ba10b3roAAdQUzqdQyP7rqARdPQgt0ClDgvtaL2TNYLc4URh7E3Kgx8T6pSFlPnU/b3cfCoVRPrr/gJBrsCkbNMITNXpVQpwIYe3P1zOrCUHuaQR82yCVUz3y43oOiE6qIY; boolean isVerified CryptoUtils.verifyBySHA256WithRSA(publicKey, test, signature); System.out.println(是否验签通过 isVerified);控制台输出 是否验签通过true4、后端加签前端验签 这里我们用后端生成的密钥对做测试。 (1) 后端代码 AsymmetricKeyPair keyPair CryptoUtils.generateAsymmetricKeyPair(Encryption.RSA_ECB_PKCS1); String privateKey keyPair.getPrivateKey(); String publicKey keyPair.getPublicKey(); System.out.println(生成的私钥为\n privateKey); System.out.println(生成的公钥为\n publicKey);String signature CryptoUtils.signBySHA256WithRSA(privateKey, test); System.out.println(生成的签名为\n signature);控制台输出如下 生成的私钥为 MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKx1iT0ObyRKC06wfWN1v9LTQwd68X1b8U5ZAh9Qf7m77HiQtLg1y91v0b70Dr/HRP7juGLFTnK5NJMcjGNqDfDFqCQtA3eam2UABbwHS76qRFQbSg5QKApvDcfOZtqWmbwwSDMkI5GnYKbSO3EZZCYBBXzplabKQCKcmGKOjAgMBAAECgYAovOb7RkKYxuje4LCFkDjeO3Jqz1KXg3wjh5Wnr7b8OJ8cXP8AyCxtFXHtcoddY/v3XeF7a3I5hZayTp6WAI1OTYhWs9Eqas8B7bNV2rJPFnK9nTiF727bgptJfGuUG8mYxRzIQleHoWqpV9i/ttcEUPM4GGcIfpnwb16NBAQJBANPBLuTCyeDbSW79MmsiTNUeCnljM/UQYUfIpygviNX1iVbsh1lI/l85bN47niIt66j4c5MPOKJOv2Hf3yYqvIECQQDQfmzfLo7deqsizkJAFKggH99ab24iCVEDtsHlsl212NC36xenoWwuIcP8fJd1UyWY5lwzzCdBKsrt0UeSd4jAkBwrv3AWHPLh4YFXRHGdyNBydGzFPpiL8xEwd9KADmlhqSuh2wgqpyjAGGJV2aPKuKaGRAXro5jQRFFjgOfHGBAkEAsq22ViqLa0nmgmSrqElLsIRAITvf8bOqHwJwOXfDXmLGgZg5G7nVLxdlQIgEQuA6y6O960zVB6vpmgRtasC5awJBAJkwLiKikvPxC8vwhZvkjrUrbDorUKcuCyDVYxXsSNW8SNsAV54wEI1Mem5LOhNPKbum6bwwfTf74gC/l4jtw 生成的公钥为 MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCsdYk9Dm8kSgtOsH/ljdb/S00MHevF9W/FOfmQIfUH5ux4kLS4Ncvdb9G9A6/x0T47hixU5yufjSTHIxjag3wxagkLQN3mptlAAW8B0uqkRUG0oOUCgKbw3Hzmbalpm8MEgzJCORp2Cm0jtxGWQmAQV86ZWmykAinJhijowIDAQAB 生成的签名为 JQ2FWaAbHWIkl4uSIxyMNbARFzSNKc7mOtXidm7hCRN85D8DVgZll02DYcWRSnn/ejOOxOrEPF8AcYHWx1repHh/jHcwv2focjF3Yne7NkQ4yGvgILDD2s1BIEfU0EH3tFLMIebyU8V54eMMtjDLQ65LZB6PH5X8s3F6yAPI70(2) 前端代码 const publicKey -----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCsdYk9Dm8kSgtOsH/ljdb/S00MHevF9W/FOfmQIfUH5ux4kLS4Ncvdb9G9A6/x0T47hixU5yufjSTHIxjag3wxagkLQN3mptlAAW8B0uqkRUG0oOUCgKbw3Hzmbalpm8MEgzJCORp2Cm0jtxGWQmAQV86ZWmykAinJhijowIDAQAB-----END PUBLIC KEY-----; const signature JQ2FWaAbHWIkl4uSIxyMNbARFzSNKc7mOtXidm7hCRN85D8DVgZll02DYcWRSnn/ejOOxOrEPF8AcYHWx1repHh/jHcwv2focjF3Yne7NkQ4yGvgILDD2s1BIEfU0EH3tFLMIebyU8V54eMMtjDLQ65LZB6PH5X8s3F6yAPI70; const message test; const isVerified CryptoUtils.verifyBySHA256WithRSA(publicKey, signature, message); console.log(是否验签通过${isVerified});控制台输出如下 是否验签通过true备注因为我们在前端解析密钥时读取的是标准pem格式密钥所以从后端复制过来的公钥一定要加上-----BEGIN PUBLIC KEY-----前缀和-----END PUBLIC KEY-----后缀否则会报错。
http://www.dnsts.com.cn/news/33186.html

相关文章:

  • 网站设计公司 无锡怎么把网站做二维码
  • 网站网络营销推广制作网站建设综合技术
  • 株洲网站建设开发设计南通网站开发招聘
  • 视频网站开发工程师wordpress转服务器
  • 望牛墩仿做网站好听的网站名称
  • 做软件开发视频网站在线设计平台排行榜
  • 电子商务网站建设参考书龙岩网络图书馆
  • 故乡网站开发的意义大气好寓意的广告公司名字
  • xp做网站拼多多网上购物商城
  • 网站加关键词桂林市人口
  • 从事网站建设的工资公司网络组建设计与方案
  • 赤峰市哪里做网站百度网站引流怎么做
  • 百度网站 v怎么怎做wordpress能自己编码么
  • win10建设网站目录情侣主题 wordpress
  • 建设通网站vip建设网站公司需要准备哪些材料
  • 河南省建设厅网站职称网网站使用标题做路径
  • wordpress可以制作什么网站泰安网站建设哪里找
  • 哈尔滨网站建设教程最好的网站优化公司
  • 西南大学校园网站建设往年考试卷常德做网站专业公司哪家好
  • 昆山做网站的个人网站建设公司i
  • 贵阳监理建设网站网站内做动图
  • 响应式相册网站商城网站建设市场分析论文
  • 企业网站管理系统使用教程优秀的吉祥物设计网站
  • 管理网站建设源代码程序什么是企业网站策划案
  • 网站建设公司哪好关掉wordpress站点
  • 千灯网站建设wordpress适应手机
  • 注册域名之后如何建设网站百度搜索网站介绍
  • 装企营销网站建设wordpress 全局变量
  • 工业产品设计展板柳州做网站优化
  • 南昌专门做网站的公司wordpress 时光轴代码