RSA签名加密解密
目录
- Java 接口
- RSAUtils.java
- 示例中的依赖
- 生成密钥对示例
- 签名示例
- 验证签名示例
- 加密和解密示例
- Javascript 接口
- 引入依赖
- 生成密钥对示例
- 签名示例
- 验证签名示例
- 加密和解密示例
- 说在最后
Java 接口
- 支持的密钥长度包括4种 RSA512、RSA1024、RSA2048、RSA4096
- 支持的签名算法包括7种 MD2withRSA、MD5withRSA、SHA1withRSA、SHA224withRSA、SHA256withRSA、SHA384withRSA、SHA512withRSA
- 对明文及密文长度没有限制
- 其中,java6 不支持签名算法 SHA224withRSA、SHA256withRSA、SHA384withRSA、SHA512withRSA
- 其中 java.util.Base64 为 java8 及以上版本支持的 API,低于 java8 的版本需要替换为其他工具类库。
RSAUtils.java
package com.sm;import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;import javax.crypto.Cipher;/*** * @Description: RSA签名,加解密处理核心文件*/
public final class RSAUtils {/*** 加密算法RSA*/private static final String KEY_ALGORITHM = "RSA";/*** 获取公钥的key*/public static final String PUBLIC_KEY = "RSAPublicKey";/*** 获取私钥的key*/public static final String PRIVATE_KEY = "RSAPrivateKey";public static RSAEncrypt getRSA512() {return RSAEncrypt.RSA512;}public static RSAEncrypt getRSA1024() {return RSAEncrypt.RSA1024;}public static RSAEncrypt getRSA2048() {return RSAEncrypt.RSA2048;}public static RSAEncrypt getRSA4096() {return RSAEncrypt.RSA4096;}/*** <p>* 获取私钥* </p>** @param keyMap 密钥对* @return* @throws Exception*/public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {Key key = (Key) keyMap.get(PRIVATE_KEY);return Base64.getEncoder().encodeToString(key.getEncoded());}/*** <p>* 获取公钥* </p>** @param keyMap 密钥对* @return* @throws Exception*/public static String getPublicKey(Map<String, Object> keyMap) throws Exception {Key key = (Key) keyMap.get(PUBLIC_KEY);return Base64.getEncoder().encodeToString(key.getEncoded());}/*** @param content* @param charset* @return* @throws SignatureException* @throws UnsupportedEncodingException*/private static byte[] getContentBytes(String content, String charset) {if (charset == null || "".equals(charset)) {return content.getBytes();}try {return content.getBytes(charset);} catch (UnsupportedEncodingException e) {throw new RuntimeException("UnsupportedEncoding:" + charset, e);}}public static enum RSAEncryptEnum {RSA512(512, 53, 64),RSA1024(1024, 117, 128),RSA2048(2048, 245, 256),RSA4096(4096, 501, 512);/*** RSA key的长度*/private final int keysize;/*** RSA最大加密明文大小*/private final int maxEncryptBlock;/*** RSA最大解密密文大小*/private final int maxDecryptBlock;private RSAEncryptEnum(int keysize, int maxEncryptBlock, int maxDecryptBlock) {this.keysize = keysize;this.maxEncryptBlock = maxEncryptBlock;this.maxDecryptBlock = maxDecryptBlock;}public int getKeysize() {return keysize;}public int getMaxEncryptBlock() {return maxEncryptBlock;}public int getMaxDecryptBlock() {return maxDecryptBlock;}}public static final class RSAEncrypt {private final RSAEncryptEnum rsaEncryptEnum;private RSAEncrypt(RSAEncryptEnum rsaEncryptEnum) {this.rsaEncryptEnum = rsaEncryptEnum;}static final RSAEncrypt RSA512 = new RSAEncrypt(RSAEncryptEnum.RSA512);static final RSAEncrypt RSA1024 = new RSAEncrypt(RSAEncryptEnum.RSA1024);static final RSAEncrypt RSA2048 = new RSAEncrypt(RSAEncryptEnum.RSA2048);static final RSAEncrypt RSA4096 = new RSAEncrypt(RSAEncryptEnum.RSA4096);/*** <p>* 生成密钥对(公钥和私钥)* </p>** @return* @throws Exception*/public Map<String, Object> genKeyPair() throws Exception {KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);keyPairGen.initialize(this.rsaEncryptEnum.getKeysize());KeyPair keyPair = keyPairGen.generateKeyPair();RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();Map<String, Object> keyMap = new HashMap<>(2, 1.0f);keyMap.put(PUBLIC_KEY, publicKey);keyMap.put(PRIVATE_KEY, privateKey);return keyMap;}/*** <P>* 私钥解密* </p>** @param encryptedData 已加密数据* @param privateKey 私钥(BASE64编码)* @return* @throws Exception*/public byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) throws Exception {byte[] keyBytes = Base64.getDecoder().decode(privateKey);PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, privateK);int inputLen = encryptedData.length;ByteArrayOutputStream out = new ByteArrayOutputStream();int offSet = 0;byte[] cache;int i = 0;int maxDecryptBlock = this.rsaEncryptEnum.getMaxDecryptBlock();// 对数据分段解密while (inputLen - offSet > 0) {if (inputLen - offSet > maxDecryptBlock) {cache = cipher.doFinal(encryptedData, offSet, maxDecryptBlock);} else {cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);}out.write(cache, 0, cache.length);i++;offSet = i * maxDecryptBlock;}byte[] decryptedData = out.toByteArray();out.close();return decryptedData;}/*** <p>* 公钥解密* </p>** @param encryptedData 已加密数据* @param publicKey 公钥(BASE64编码)* @return* @throws Exception*/public byte[] decryptByPublicKey(byte[] encryptedData, String publicKey) throws Exception {byte[] keyBytes = Base64.getDecoder().decode(publicKey);X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);Key publicK = keyFactory.generatePublic(x509KeySpec);Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, publicK);int inputLen = encryptedData.length;ByteArrayOutputStream out = new ByteArrayOutputStream();int offSet = 0;byte[] cache;int i = 0;int maxDecryptBlock = this.rsaEncryptEnum.getMaxDecryptBlock();// 对数据分段解密while (inputLen - offSet > 0) {if (inputLen - offSet > maxDecryptBlock) {cache = cipher.doFinal(encryptedData, offSet, maxDecryptBlock);} else {cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);}out.write(cache, 0, cache.length);i++;offSet = i * maxDecryptBlock;}byte[] decryptedData = out.toByteArray();out.close();return decryptedData;}/*** <p>* 公钥加密* </p>** @param data 源数据* @param publicKey 公钥(BASE64编码)* @return* @throws Exception*/public byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {byte[] keyBytes = Base64.getDecoder().decode(publicKey);X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);Key publicK = keyFactory.generatePublic(x509KeySpec);// 对数据加密Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, publicK);int inputLen = data.length;ByteArrayOutputStream out = new ByteArrayOutputStream();int offSet = 0;byte[] cache;int i = 0;int maxEncryptBlock = this.rsaEncryptEnum.getMaxEncryptBlock();// 对数据分段加密while (inputLen - offSet > 0) {if (inputLen - offSet > maxEncryptBlock) {cache = cipher.doFinal(data, offSet, maxEncryptBlock);} else {cache = cipher.doFinal(data, offSet, inputLen - offSet);}out.write(cache, 0, cache.length);i++;offSet = i * maxEncryptBlock;}byte[] encryptedData = out.toByteArray();out.close();return encryptedData;}/*** <p>* 私钥加密* </p>** @param data 源数据* @param privateKey 私钥(BASE64编码)* @return* @throws Exception*/public byte[] encryptByPrivateKey(byte[] data, String privateKey) throws Exception {byte[] keyBytes = Base64.getDecoder().decode(privateKey);PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, privateK);int inputLen = data.length;ByteArrayOutputStream out = new ByteArrayOutputStream();int offSet = 0;byte[] cache;int i = 0;int maxEncryptBlock = this.rsaEncryptEnum.getMaxEncryptBlock();// 对数据分段加密while (inputLen - offSet > 0) {if (inputLen - offSet > maxEncryptBlock) {cache = cipher.doFinal(data, offSet, maxEncryptBlock);} else {cache = cipher.doFinal(data, offSet, inputLen - offSet);}out.write(cache, 0, cache.length);i++;offSet = i * maxEncryptBlock;}byte[] encryptedData = out.toByteArray();out.close();return encryptedData;}}public static RSASignature getMD2withRSA() {return RSASignature.MD2_WITH_RSA;}public static RSASignature getMD5withRSA() {return RSASignature.MD5_WITH_RSA;}public static RSASignature getSHA1withRSA() {return RSASignature.SHA1_WITH_RSA;}public static RSASignature getSHA224withRSA() {return RSASignature.SHA224_WITH_RSA;}public static RSASignature getSHA256withRSA() {return RSASignature.SHA256_WITH_RSA;}public static RSASignature getSHA384withRSA() {return RSASignature.SHA384_WITH_RSA;}public static RSASignature getSHA512withRSA() {return RSASignature.SHA512_WITH_RSA;}public static final class RSASignature {/*** 签名算法*/private final String signatureAlgorithm;private RSASignature(String signatureAlgorithm) {this.signatureAlgorithm = signatureAlgorithm;}static final RSASignature MD2_WITH_RSA = new RSASignature("MD2withRSA");static final RSASignature MD5_WITH_RSA = new RSASignature("MD5withRSA");static final RSASignature SHA1_WITH_RSA = new RSASignature("SHA1withRSA");static final RSASignature SHA224_WITH_RSA = new RSASignature("SHA224withRSA");static final RSASignature SHA256_WITH_RSA = new RSASignature("SHA256withRSA");static final RSASignature SHA384_WITH_RSA = new RSASignature("SHA384withRSA");static final RSASignature SHA512_WITH_RSA = new RSASignature("SHA512withRSA");/*** 签名字符串** @param text* 需要签名的字符串* @param privateKey 私钥(BASE64编码)** @param charset* 编码格式* @return 签名结果(BASE64编码)*/public String sign(String text, String privateKey, String charset) throws Exception {byte[] keyBytes = Base64.getDecoder().decode(privateKey);PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);Signature signature = Signature.getInstance(this.signatureAlgorithm);signature.initSign(privateK);signature.update(getContentBytes(text, charset));byte[] result = signature.sign();return Base64.getEncoder().encodeToString(result);}/*** 签名字符串** @param text* 需要签名的字符串* @param sign* 客户签名结果* @param publicKey* 公钥(BASE64编码)* @param charset* 编码格式* @return 验签结果*/public boolean verify(String text, String sign, String publicKey, String charset) throws Exception {byte[] keyBytes = Base64.getDecoder().decode(publicKey);X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);PublicKey publicK = keyFactory.generatePublic(keySpec);Signature signature = Signature.getInstance(this.signatureAlgorithm);signature.initVerify(publicK);signature.update(getContentBytes(text, charset));return signature.verify(Base64.getDecoder().decode(sign));}}}
示例中的依赖
import java.util.Base64;
import java.util.Map;import com.sm.RSAUtils.RSAEncrypt;
import com.sm.RSAUtils.RSASignature;
生成密钥对示例
public static void genKeyPair () throws Exception {RSAEncrypt rsaEncrypt = RSAUtils.getRSA1024();//生成密钥对Map<String, Object> map = rsaEncrypt.genKeyPair();String pubKey = RSAUtils.getPublicKey(map);String priKey = RSAUtils.getPrivateKey(map);System.out.println("pubKey-->"+pubKey);System.out.println("priKey-->"+priKey);
}
签名示例
public static void sign() throws Exception {String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnsXBwH6me+8+P3BdtnZnsze3nQXCmt8+9+jcLmxK+Q2Oe6qQ3hfElokUpWBLogEgmoj5/dF+xWaQYAzvd1LR7zuKDESQmRnOb9FQD6Pr2RsDOTFBCa5DA0EQ17TmqqaJT9+xrcIVxU/Y2+2tCkRJBJuo7hRoFoM2l37ju9InTGA9P/vQXi9jjSiZ5o6Zbu6svHG1B/1GsnC+wtszYzsMZs7Lo2N5lK2e+q2bBnpvb7PpWOWTGVpeFoivbH+fCIRB6wiFAiQxeZ++KNs2Coi7zoj6cOX49aG4rv4/gnwftOKq4Fb9I+cQW5v7d3Nmp6Jh647DshTEwpLlyxt1J0feUQIDAQAB";String priKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCexcHAfqZ77z4/cF22dmezN7edBcKa3z736NwubEr5DY57qpDeF8SWiRSlYEuiASCaiPn90X7FZpBgDO93UtHvO4oMRJCZGc5v0VAPo+vZGwM5MUEJrkMDQRDXtOaqpolP37GtwhXFT9jb7a0KREkEm6juFGgWgzaXfuO70idMYD0/+9BeL2ONKJnmjplu7qy8cbUH/UaycL7C2zNjOwxmzsujY3mUrZ76rZsGem9vs+lY5ZMZWl4WiK9sf58IhEHrCIUCJDF5n74o2zYKiLvOiPpw5fj1obiu/j+CfB+04qrgVv0j5xBbm/t3c2anomHrjsOyFMTCkuXLG3UnR95RAgMBAAECggEAJP8BqcAZPRG/WHrvaz/l5A3cnBsmgH36pzu8apjTU3tEMy7IeOfi6AzjIbHxjbtjhH7cebdiKc8/XxJEjnJe9rbR8Q/c/b/UqZuFY0+X+kvgEWiXthDEDrMPoKPHiAYsQs9mEI4EEqkLaBvW0Wid9xPqZiedJXnHs79eg3pxq8r3JNCLfgG3sl+2WkaAyhPXcG9Pw5E1WjxAQqcW79i8Wk1LQHonWXoE3/HisFMFQNGb0s8iAjord+M/OdEgr64hZypkpnXZ4xtopeeVjVfA6km/UHwl4UHjUvj2OvgHIYNniHx0Ap6W3Q8ef9ncy2oXbZvKlHYu0AykheCLJ7P0/QKBgQDLlxYcPMdSq19QJD9PJJTmD9IO75uNxX2ITsBuiSk81LqiYFm2x9EsKQF7lqZ1xPcoQu/AW1CrO3J9HSSsW4D27yO8dMgL38jT5O5lDiF+Fs+f3c5LDq8vCvXEF5MARo5rgyX7CMJjo1tFoDEX1zEfoBoMmoFfxFuOTlx8/zRHDwKBgQDHpR0nNGnDmW1GtU2uBnrxZo4cTIA3kZPEoQJIrvVkkQ/k1fuZMtzYTsSSEG4b1ZI2tdqm8wItQ50gXyQOCZ6B7kSkU/xelPCEfK7zRObPLS1IOyiayNw7aAwmZI2GERAm9TBlewn2PCJGT9F1vDGTb8M70tkgl8PUXm+XnBSEnwKBgCbKb80Li5Ll0jBL58AloTVAmG5+Gu5lTajWEHY/LhtIERN1NkLMSb+XRJAOwUK5N7p1HodRHsqxdfv+vIkWmjjykaWLvr38cqBlA0M/8QO8Ru0X7wGAF8Ln3LHzJ/AqgWJcx7TQE3G2o2JdxlzbhKGY+L2kBrh/ik5QAfFTEtvjAoGATBWQ1rAS3ohKLPhLclbl47nBzucYthS0y+rQhAKpYnomJH+oMuo/X/Ak2cWJMPJjlpYXjihuW/G4n+2iP/dKgRnc7wNS2njIcLVTt0I69BmzeCOThemmhL1SZA9OIBnAnhgzKXmKglzIcyNYIBZojle5f8MLHHC6IOUcghrpduECgYEAlZgVK0trRmi+Dy2lmkhmBXckq1Xle1cJac3zZYeg9+Cd424WDyqhl2SFNDrvvTGCW9PtONMQBXUxnbImWDb8lw4ClY2tR0XZe0YycGMcV983PsTjJqET+8oGPVLGmnlCLJ4X9raQYKDWpDyGOFfX91QsFOnnSprTrylhjnhC3ko=";String text = "id_card=1121321121321321中文2123123&partner_id=TLHS2020001";final String charset = "utf-8";RSASignature rsaSignature = RSAUtils.getSHA256withRSA();String sign = rsaSignature.sign(text, priKey, charset);System.out.println("sign-->"+sign);
}
验证签名示例
public static void verify() throws Exception {String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnsXBwH6me+8+P3BdtnZnsze3nQXCmt8+9+jcLmxK+Q2Oe6qQ3hfElokUpWBLogEgmoj5/dF+xWaQYAzvd1LR7zuKDESQmRnOb9FQD6Pr2RsDOTFBCa5DA0EQ17TmqqaJT9+xrcIVxU/Y2+2tCkRJBJuo7hRoFoM2l37ju9InTGA9P/vQXi9jjSiZ5o6Zbu6svHG1B/1GsnC+wtszYzsMZs7Lo2N5lK2e+q2bBnpvb7PpWOWTGVpeFoivbH+fCIRB6wiFAiQxeZ++KNs2Coi7zoj6cOX49aG4rv4/gnwftOKq4Fb9I+cQW5v7d3Nmp6Jh647DshTEwpLlyxt1J0feUQIDAQAB";String priKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCexcHAfqZ77z4/cF22dmezN7edBcKa3z736NwubEr5DY57qpDeF8SWiRSlYEuiASCaiPn90X7FZpBgDO93UtHvO4oMRJCZGc5v0VAPo+vZGwM5MUEJrkMDQRDXtOaqpolP37GtwhXFT9jb7a0KREkEm6juFGgWgzaXfuO70idMYD0/+9BeL2ONKJnmjplu7qy8cbUH/UaycL7C2zNjOwxmzsujY3mUrZ76rZsGem9vs+lY5ZMZWl4WiK9sf58IhEHrCIUCJDF5n74o2zYKiLvOiPpw5fj1obiu/j+CfB+04qrgVv0j5xBbm/t3c2anomHrjsOyFMTCkuXLG3UnR95RAgMBAAECggEAJP8BqcAZPRG/WHrvaz/l5A3cnBsmgH36pzu8apjTU3tEMy7IeOfi6AzjIbHxjbtjhH7cebdiKc8/XxJEjnJe9rbR8Q/c/b/UqZuFY0+X+kvgEWiXthDEDrMPoKPHiAYsQs9mEI4EEqkLaBvW0Wid9xPqZiedJXnHs79eg3pxq8r3JNCLfgG3sl+2WkaAyhPXcG9Pw5E1WjxAQqcW79i8Wk1LQHonWXoE3/HisFMFQNGb0s8iAjord+M/OdEgr64hZypkpnXZ4xtopeeVjVfA6km/UHwl4UHjUvj2OvgHIYNniHx0Ap6W3Q8ef9ncy2oXbZvKlHYu0AykheCLJ7P0/QKBgQDLlxYcPMdSq19QJD9PJJTmD9IO75uNxX2ITsBuiSk81LqiYFm2x9EsKQF7lqZ1xPcoQu/AW1CrO3J9HSSsW4D27yO8dMgL38jT5O5lDiF+Fs+f3c5LDq8vCvXEF5MARo5rgyX7CMJjo1tFoDEX1zEfoBoMmoFfxFuOTlx8/zRHDwKBgQDHpR0nNGnDmW1GtU2uBnrxZo4cTIA3kZPEoQJIrvVkkQ/k1fuZMtzYTsSSEG4b1ZI2tdqm8wItQ50gXyQOCZ6B7kSkU/xelPCEfK7zRObPLS1IOyiayNw7aAwmZI2GERAm9TBlewn2PCJGT9F1vDGTb8M70tkgl8PUXm+XnBSEnwKBgCbKb80Li5Ll0jBL58AloTVAmG5+Gu5lTajWEHY/LhtIERN1NkLMSb+XRJAOwUK5N7p1HodRHsqxdfv+vIkWmjjykaWLvr38cqBlA0M/8QO8Ru0X7wGAF8Ln3LHzJ/AqgWJcx7TQE3G2o2JdxlzbhKGY+L2kBrh/ik5QAfFTEtvjAoGATBWQ1rAS3ohKLPhLclbl47nBzucYthS0y+rQhAKpYnomJH+oMuo/X/Ak2cWJMPJjlpYXjihuW/G4n+2iP/dKgRnc7wNS2njIcLVTt0I69BmzeCOThemmhL1SZA9OIBnAnhgzKXmKglzIcyNYIBZojle5f8MLHHC6IOUcghrpduECgYEAlZgVK0trRmi+Dy2lmkhmBXckq1Xle1cJac3zZYeg9+Cd424WDyqhl2SFNDrvvTGCW9PtONMQBXUxnbImWDb8lw4ClY2tR0XZe0YycGMcV983PsTjJqET+8oGPVLGmnlCLJ4X9raQYKDWpDyGOFfX91QsFOnnSprTrylhjnhC3ko=";String text = "id_card=1121321121321321中文2123123&partner_id=TLHS2020001";String sign = "GAjmZiUH0hnMOZyOiViCvzZDHoMVXdmwjyyLiAOgBYFhM0/d8GPiPMKZsPIAmIKiDRwX37bOoG+wD4/Miptq5+3tmt8Cqktzv8v2Z6kGNejkJl9Mos5lgRI7kdFf9GMiQuy3lvRybOT8S0HFGr2vFrMrUrkYL9W+PzlILS7sQuerLqVm0xKIuj5/thm8L5kcVQFozudxydbYxsBp8pvSqsVRCZ4mPO/S6I1NTeS7ffLGixrmyWsXEVX9/D11WGgN3UYrNlEVna9Y4VOk9o9bB8un/FaJyyMuIHpT0YYLjZxAO2GpxuD9dsJbEL990Lr5k+P66mCeC5mNX/s2jBI49w==";final String charset = "utf-8";RSASignature rsaSignature = RSAUtils.getSHA256withRSA();if(rsaSignature.verify(text, sign, pubKey, charset)) {System.out.println("验签成功");}else {System.out.println("验签失败");}
}
加密和解密示例
public static void encryptAndDecrypt() throws Exception {RSAEncrypt rsaEncrypt = RSAUtils.getRSA2048();String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnsXBwH6me+8+P3BdtnZnsze3nQXCmt8+9+jcLmxK+Q2Oe6qQ3hfElokUpWBLogEgmoj5/dF+xWaQYAzvd1LR7zuKDESQmRnOb9FQD6Pr2RsDOTFBCa5DA0EQ17TmqqaJT9+xrcIVxU/Y2+2tCkRJBJuo7hRoFoM2l37ju9InTGA9P/vQXi9jjSiZ5o6Zbu6svHG1B/1GsnC+wtszYzsMZs7Lo2N5lK2e+q2bBnpvb7PpWOWTGVpeFoivbH+fCIRB6wiFAiQxeZ++KNs2Coi7zoj6cOX49aG4rv4/gnwftOKq4Fb9I+cQW5v7d3Nmp6Jh647DshTEwpLlyxt1J0feUQIDAQAB";String priKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCexcHAfqZ77z4/cF22dmezN7edBcKa3z736NwubEr5DY57qpDeF8SWiRSlYEuiASCaiPn90X7FZpBgDO93UtHvO4oMRJCZGc5v0VAPo+vZGwM5MUEJrkMDQRDXtOaqpolP37GtwhXFT9jb7a0KREkEm6juFGgWgzaXfuO70idMYD0/+9BeL2ONKJnmjplu7qy8cbUH/UaycL7C2zNjOwxmzsujY3mUrZ76rZsGem9vs+lY5ZMZWl4WiK9sf58IhEHrCIUCJDF5n74o2zYKiLvOiPpw5fj1obiu/j+CfB+04qrgVv0j5xBbm/t3c2anomHrjsOyFMTCkuXLG3UnR95RAgMBAAECggEAJP8BqcAZPRG/WHrvaz/l5A3cnBsmgH36pzu8apjTU3tEMy7IeOfi6AzjIbHxjbtjhH7cebdiKc8/XxJEjnJe9rbR8Q/c/b/UqZuFY0+X+kvgEWiXthDEDrMPoKPHiAYsQs9mEI4EEqkLaBvW0Wid9xPqZiedJXnHs79eg3pxq8r3JNCLfgG3sl+2WkaAyhPXcG9Pw5E1WjxAQqcW79i8Wk1LQHonWXoE3/HisFMFQNGb0s8iAjord+M/OdEgr64hZypkpnXZ4xtopeeVjVfA6km/UHwl4UHjUvj2OvgHIYNniHx0Ap6W3Q8ef9ncy2oXbZvKlHYu0AykheCLJ7P0/QKBgQDLlxYcPMdSq19QJD9PJJTmD9IO75uNxX2ITsBuiSk81LqiYFm2x9EsKQF7lqZ1xPcoQu/AW1CrO3J9HSSsW4D27yO8dMgL38jT5O5lDiF+Fs+f3c5LDq8vCvXEF5MARo5rgyX7CMJjo1tFoDEX1zEfoBoMmoFfxFuOTlx8/zRHDwKBgQDHpR0nNGnDmW1GtU2uBnrxZo4cTIA3kZPEoQJIrvVkkQ/k1fuZMtzYTsSSEG4b1ZI2tdqm8wItQ50gXyQOCZ6B7kSkU/xelPCEfK7zRObPLS1IOyiayNw7aAwmZI2GERAm9TBlewn2PCJGT9F1vDGTb8M70tkgl8PUXm+XnBSEnwKBgCbKb80Li5Ll0jBL58AloTVAmG5+Gu5lTajWEHY/LhtIERN1NkLMSb+XRJAOwUK5N7p1HodRHsqxdfv+vIkWmjjykaWLvr38cqBlA0M/8QO8Ru0X7wGAF8Ln3LHzJ/AqgWJcx7TQE3G2o2JdxlzbhKGY+L2kBrh/ik5QAfFTEtvjAoGATBWQ1rAS3ohKLPhLclbl47nBzucYthS0y+rQhAKpYnomJH+oMuo/X/Ak2cWJMPJjlpYXjihuW/G4n+2iP/dKgRnc7wNS2njIcLVTt0I69BmzeCOThemmhL1SZA9OIBnAnhgzKXmKglzIcyNYIBZojle5f8MLHHC6IOUcghrpduECgYEAlZgVK0trRmi+Dy2lmkhmBXckq1Xle1cJac3zZYeg9+Cd424WDyqhl2SFNDrvvTGCW9PtONMQBXUxnbImWDb8lw4ClY2tR0XZe0YycGMcV983PsTjJqET+8oGPVLGmnlCLJ4X9raQYKDWpDyGOFfX91QsFOnnSprTrylhjnhC3ko=";String text = "id_card=1121321121321321中文2123123&partner_id=TLHS2020001";// 加密与解密byte[] data = text.getBytes();System.out.println("加密前--->" + new String(data));byte[] encryptedDataPri = rsaEncrypt.encryptByPrivateKey(data, priKey);// 密文System.out.println("私钥加密后--->" + Base64.getEncoder().encodeToString(encryptedDataPri));byte[] decryptedDataPub = rsaEncrypt.decryptByPublicKey(encryptedDataPri, pubKey);System.out.println("公钥解密后--->"+new String(decryptedDataPub));byte[] encryptedDataPub = rsaEncrypt.encryptByPublicKey(data, pubKey);// 密文System.out.println("公钥加密后--->" + Base64.getEncoder().encodeToString(encryptedDataPub));byte[] decryptedDataPri = rsaEncrypt.decryptByPrivateKey(encryptedDataPub, priKey);System.out.println("私钥解密后--->"+new String(decryptedDataPri));
}
Javascript 接口
- jsencrypt 支持的密钥长度包括4种 RSA512、RSA1024、RSA2048、RSA4096
- crypto-js 支持的签名算法包括 MD5、SHA1、SHA224、SHA256、SHA384、SHA512 等多种算法
- 对明文及密文长度有限制,超长会报错,可以查看 https://github.com/travist/jsencrypt/issues/110 尝试解决
- 经测试,jsencrypt 不支持使用私钥加密,即由私钥加密产生的密文不能被解密。
引入依赖
github链接
https://github.com/travist/jsencrypt
https://github.com/brix/crypto-js/tree/4.1.1
<script type="text/javascript" src="jsencrypt.min.js"></script>
<script type="text/javascript" src="crypto-js.js"></script>
生成密钥对示例
(function () {//生成密钥对var crypt = new JSEncrypt({default_key_size: 2048});crypt.getKey();console.log('PrivateKey', crypt.getPrivateKey());console.log('PublicKey', crypt.getPublicKey());
})();
签名示例
(function () {//RSA2048签名var pubKey = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnsXBwH6me+8+P3BdtnZnsze3nQXCmt8+9+jcLmxK+Q2Oe6qQ3hfElokUpWBLogEgmoj5/dF+xWaQYAzvd1LR7zuKDESQmRnOb9FQD6Pr2RsDOTFBCa5DA0EQ17TmqqaJT9+xrcIVxU/Y2+2tCkRJBJuo7hRoFoM2l37ju9InTGA9P/vQXi9jjSiZ5o6Zbu6svHG1B/1GsnC+wtszYzsMZs7Lo2N5lK2e+q2bBnpvb7PpWOWTGVpeFoivbH+fCIRB6wiFAiQxeZ++KNs2Coi7zoj6cOX49aG4rv4/gnwftOKq4Fb9I+cQW5v7d3Nmp6Jh647DshTEwpLlyxt1J0feUQIDAQAB';var priKey = 'MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCexcHAfqZ77z4/cF22dmezN7edBcKa3z736NwubEr5DY57qpDeF8SWiRSlYEuiASCaiPn90X7FZpBgDO93UtHvO4oMRJCZGc5v0VAPo+vZGwM5MUEJrkMDQRDXtOaqpolP37GtwhXFT9jb7a0KREkEm6juFGgWgzaXfuO70idMYD0/+9BeL2ONKJnmjplu7qy8cbUH/UaycL7C2zNjOwxmzsujY3mUrZ76rZsGem9vs+lY5ZMZWl4WiK9sf58IhEHrCIUCJDF5n74o2zYKiLvOiPpw5fj1obiu/j+CfB+04qrgVv0j5xBbm/t3c2anomHrjsOyFMTCkuXLG3UnR95RAgMBAAECggEAJP8BqcAZPRG/WHrvaz/l5A3cnBsmgH36pzu8apjTU3tEMy7IeOfi6AzjIbHxjbtjhH7cebdiKc8/XxJEjnJe9rbR8Q/c/b/UqZuFY0+X+kvgEWiXthDEDrMPoKPHiAYsQs9mEI4EEqkLaBvW0Wid9xPqZiedJXnHs79eg3pxq8r3JNCLfgG3sl+2WkaAyhPXcG9Pw5E1WjxAQqcW79i8Wk1LQHonWXoE3/HisFMFQNGb0s8iAjord+M/OdEgr64hZypkpnXZ4xtopeeVjVfA6km/UHwl4UHjUvj2OvgHIYNniHx0Ap6W3Q8ef9ncy2oXbZvKlHYu0AykheCLJ7P0/QKBgQDLlxYcPMdSq19QJD9PJJTmD9IO75uNxX2ITsBuiSk81LqiYFm2x9EsKQF7lqZ1xPcoQu/AW1CrO3J9HSSsW4D27yO8dMgL38jT5O5lDiF+Fs+f3c5LDq8vCvXEF5MARo5rgyX7CMJjo1tFoDEX1zEfoBoMmoFfxFuOTlx8/zRHDwKBgQDHpR0nNGnDmW1GtU2uBnrxZo4cTIA3kZPEoQJIrvVkkQ/k1fuZMtzYTsSSEG4b1ZI2tdqm8wItQ50gXyQOCZ6B7kSkU/xelPCEfK7zRObPLS1IOyiayNw7aAwmZI2GERAm9TBlewn2PCJGT9F1vDGTb8M70tkgl8PUXm+XnBSEnwKBgCbKb80Li5Ll0jBL58AloTVAmG5+Gu5lTajWEHY/LhtIERN1NkLMSb+XRJAOwUK5N7p1HodRHsqxdfv+vIkWmjjykaWLvr38cqBlA0M/8QO8Ru0X7wGAF8Ln3LHzJ/AqgWJcx7TQE3G2o2JdxlzbhKGY+L2kBrh/ik5QAfFTEtvjAoGATBWQ1rAS3ohKLPhLclbl47nBzucYthS0y+rQhAKpYnomJH+oMuo/X/Ak2cWJMPJjlpYXjihuW/G4n+2iP/dKgRnc7wNS2njIcLVTt0I69BmzeCOThemmhL1SZA9OIBnAnhgzKXmKglzIcyNYIBZojle5f8MLHHC6IOUcghrpduECgYEAlZgVK0trRmi+Dy2lmkhmBXckq1Xle1cJac3zZYeg9+Cd424WDyqhl2SFNDrvvTGCW9PtONMQBXUxnbImWDb8lw4ClY2tR0XZe0YycGMcV983PsTjJqET+8oGPVLGmnlCLJ4X9raQYKDWpDyGOFfX91QsFOnnSprTrylhjnhC3ko=';//SHA256withRSAvar plainText = 'id_card=1121321121321321中文2123123&partner_id=TLHS2020001';//**加签**var sign = new JSEncrypt();//设置私钥sign.setPrivateKey(priKey);//用私钥给明文加签,例子中使用SHA256算法,具体情况具体调整var signature = sign.sign(plainText, CryptoJS.SHA256, "sha256");console.log('sha256签名', signature);
})();
验证签名示例
(function () {//RSA2048验签var pubKey = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnsXBwH6me+8+P3BdtnZnsze3nQXCmt8+9+jcLmxK+Q2Oe6qQ3hfElokUpWBLogEgmoj5/dF+xWaQYAzvd1LR7zuKDESQmRnOb9FQD6Pr2RsDOTFBCa5DA0EQ17TmqqaJT9+xrcIVxU/Y2+2tCkRJBJuo7hRoFoM2l37ju9InTGA9P/vQXi9jjSiZ5o6Zbu6svHG1B/1GsnC+wtszYzsMZs7Lo2N5lK2e+q2bBnpvb7PpWOWTGVpeFoivbH+fCIRB6wiFAiQxeZ++KNs2Coi7zoj6cOX49aG4rv4/gnwftOKq4Fb9I+cQW5v7d3Nmp6Jh647DshTEwpLlyxt1J0feUQIDAQAB';var priKey = 'MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCexcHAfqZ77z4/cF22dmezN7edBcKa3z736NwubEr5DY57qpDeF8SWiRSlYEuiASCaiPn90X7FZpBgDO93UtHvO4oMRJCZGc5v0VAPo+vZGwM5MUEJrkMDQRDXtOaqpolP37GtwhXFT9jb7a0KREkEm6juFGgWgzaXfuO70idMYD0/+9BeL2ONKJnmjplu7qy8cbUH/UaycL7C2zNjOwxmzsujY3mUrZ76rZsGem9vs+lY5ZMZWl4WiK9sf58IhEHrCIUCJDF5n74o2zYKiLvOiPpw5fj1obiu/j+CfB+04qrgVv0j5xBbm/t3c2anomHrjsOyFMTCkuXLG3UnR95RAgMBAAECggEAJP8BqcAZPRG/WHrvaz/l5A3cnBsmgH36pzu8apjTU3tEMy7IeOfi6AzjIbHxjbtjhH7cebdiKc8/XxJEjnJe9rbR8Q/c/b/UqZuFY0+X+kvgEWiXthDEDrMPoKPHiAYsQs9mEI4EEqkLaBvW0Wid9xPqZiedJXnHs79eg3pxq8r3JNCLfgG3sl+2WkaAyhPXcG9Pw5E1WjxAQqcW79i8Wk1LQHonWXoE3/HisFMFQNGb0s8iAjord+M/OdEgr64hZypkpnXZ4xtopeeVjVfA6km/UHwl4UHjUvj2OvgHIYNniHx0Ap6W3Q8ef9ncy2oXbZvKlHYu0AykheCLJ7P0/QKBgQDLlxYcPMdSq19QJD9PJJTmD9IO75uNxX2ITsBuiSk81LqiYFm2x9EsKQF7lqZ1xPcoQu/AW1CrO3J9HSSsW4D27yO8dMgL38jT5O5lDiF+Fs+f3c5LDq8vCvXEF5MARo5rgyX7CMJjo1tFoDEX1zEfoBoMmoFfxFuOTlx8/zRHDwKBgQDHpR0nNGnDmW1GtU2uBnrxZo4cTIA3kZPEoQJIrvVkkQ/k1fuZMtzYTsSSEG4b1ZI2tdqm8wItQ50gXyQOCZ6B7kSkU/xelPCEfK7zRObPLS1IOyiayNw7aAwmZI2GERAm9TBlewn2PCJGT9F1vDGTb8M70tkgl8PUXm+XnBSEnwKBgCbKb80Li5Ll0jBL58AloTVAmG5+Gu5lTajWEHY/LhtIERN1NkLMSb+XRJAOwUK5N7p1HodRHsqxdfv+vIkWmjjykaWLvr38cqBlA0M/8QO8Ru0X7wGAF8Ln3LHzJ/AqgWJcx7TQE3G2o2JdxlzbhKGY+L2kBrh/ik5QAfFTEtvjAoGATBWQ1rAS3ohKLPhLclbl47nBzucYthS0y+rQhAKpYnomJH+oMuo/X/Ak2cWJMPJjlpYXjihuW/G4n+2iP/dKgRnc7wNS2njIcLVTt0I69BmzeCOThemmhL1SZA9OIBnAnhgzKXmKglzIcyNYIBZojle5f8MLHHC6IOUcghrpduECgYEAlZgVK0trRmi+Dy2lmkhmBXckq1Xle1cJac3zZYeg9+Cd424WDyqhl2SFNDrvvTGCW9PtONMQBXUxnbImWDb8lw4ClY2tR0XZe0YycGMcV983PsTjJqET+8oGPVLGmnlCLJ4X9raQYKDWpDyGOFfX91QsFOnnSprTrylhjnhC3ko=';//SHA256withRSAvar plainText = 'id_card=1121321121321321中文2123123&partner_id=TLHS2020001';var signature = 'GAjmZiUH0hnMOZyOiViCvzZDHoMVXdmwjyyLiAOgBYFhM0/d8GPiPMKZsPIAmIKiDRwX37bOoG+wD4/Miptq5+3tmt8Cqktzv8v2Z6kGNejkJl9Mos5lgRI7kdFf9GMiQuy3lvRybOT8S0HFGr2vFrMrUrkYL9W+PzlILS7sQuerLqVm0xKIuj5/thm8L5kcVQFozudxydbYxsBp8pvSqsVRCZ4mPO/S6I1NTeS7ffLGixrmyWsXEVX9/D11WGgN3UYrNlEVna9Y4VOk9o9bB8un/FaJyyMuIHpT0YYLjZxAO2GpxuD9dsJbEL990Lr5k+P66mCeC5mNX/s2jBI49w==';//**验签**var verify = new JSEncrypt({default_key_size: 2048});//设置公钥verify.setPublicKey(pubKey);//验证方法有三个参数明文,用私钥加签后的字符串,加签的算法(跟上文保持一致哈~)var verified = verify.verify(plainText, signature, CryptoJS.SHA256);// 判断验签是否成功if (verified) {console.log('验签成功啦~');}else {console.log('验签失败啦....');}
})();
加密和解密示例
(function () {//RSA2048加密解密var pubKey = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnsXBwH6me+8+P3BdtnZnsze3nQXCmt8+9+jcLmxK+Q2Oe6qQ3hfElokUpWBLogEgmoj5/dF+xWaQYAzvd1LR7zuKDESQmRnOb9FQD6Pr2RsDOTFBCa5DA0EQ17TmqqaJT9+xrcIVxU/Y2+2tCkRJBJuo7hRoFoM2l37ju9InTGA9P/vQXi9jjSiZ5o6Zbu6svHG1B/1GsnC+wtszYzsMZs7Lo2N5lK2e+q2bBnpvb7PpWOWTGVpeFoivbH+fCIRB6wiFAiQxeZ++KNs2Coi7zoj6cOX49aG4rv4/gnwftOKq4Fb9I+cQW5v7d3Nmp6Jh647DshTEwpLlyxt1J0feUQIDAQAB';var priKey = 'MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCexcHAfqZ77z4/cF22dmezN7edBcKa3z736NwubEr5DY57qpDeF8SWiRSlYEuiASCaiPn90X7FZpBgDO93UtHvO4oMRJCZGc5v0VAPo+vZGwM5MUEJrkMDQRDXtOaqpolP37GtwhXFT9jb7a0KREkEm6juFGgWgzaXfuO70idMYD0/+9BeL2ONKJnmjplu7qy8cbUH/UaycL7C2zNjOwxmzsujY3mUrZ76rZsGem9vs+lY5ZMZWl4WiK9sf58IhEHrCIUCJDF5n74o2zYKiLvOiPpw5fj1obiu/j+CfB+04qrgVv0j5xBbm/t3c2anomHrjsOyFMTCkuXLG3UnR95RAgMBAAECggEAJP8BqcAZPRG/WHrvaz/l5A3cnBsmgH36pzu8apjTU3tEMy7IeOfi6AzjIbHxjbtjhH7cebdiKc8/XxJEjnJe9rbR8Q/c/b/UqZuFY0+X+kvgEWiXthDEDrMPoKPHiAYsQs9mEI4EEqkLaBvW0Wid9xPqZiedJXnHs79eg3pxq8r3JNCLfgG3sl+2WkaAyhPXcG9Pw5E1WjxAQqcW79i8Wk1LQHonWXoE3/HisFMFQNGb0s8iAjord+M/OdEgr64hZypkpnXZ4xtopeeVjVfA6km/UHwl4UHjUvj2OvgHIYNniHx0Ap6W3Q8ef9ncy2oXbZvKlHYu0AykheCLJ7P0/QKBgQDLlxYcPMdSq19QJD9PJJTmD9IO75uNxX2ITsBuiSk81LqiYFm2x9EsKQF7lqZ1xPcoQu/AW1CrO3J9HSSsW4D27yO8dMgL38jT5O5lDiF+Fs+f3c5LDq8vCvXEF5MARo5rgyX7CMJjo1tFoDEX1zEfoBoMmoFfxFuOTlx8/zRHDwKBgQDHpR0nNGnDmW1GtU2uBnrxZo4cTIA3kZPEoQJIrvVkkQ/k1fuZMtzYTsSSEG4b1ZI2tdqm8wItQ50gXyQOCZ6B7kSkU/xelPCEfK7zRObPLS1IOyiayNw7aAwmZI2GERAm9TBlewn2PCJGT9F1vDGTb8M70tkgl8PUXm+XnBSEnwKBgCbKb80Li5Ll0jBL58AloTVAmG5+Gu5lTajWEHY/LhtIERN1NkLMSb+XRJAOwUK5N7p1HodRHsqxdfv+vIkWmjjykaWLvr38cqBlA0M/8QO8Ru0X7wGAF8Ln3LHzJ/AqgWJcx7TQE3G2o2JdxlzbhKGY+L2kBrh/ik5QAfFTEtvjAoGATBWQ1rAS3ohKLPhLclbl47nBzucYthS0y+rQhAKpYnomJH+oMuo/X/Ak2cWJMPJjlpYXjihuW/G4n+2iP/dKgRnc7wNS2njIcLVTt0I69BmzeCOThemmhL1SZA9OIBnAnhgzKXmKglzIcyNYIBZojle5f8MLHHC6IOUcghrpduECgYEAlZgVK0trRmi+Dy2lmkhmBXckq1Xle1cJac3zZYeg9+Cd424WDyqhl2SFNDrvvTGCW9PtONMQBXUxnbImWDb8lw4ClY2tR0XZe0YycGMcV983PsTjJqET+8oGPVLGmnlCLJ4X9raQYKDWpDyGOFfX91QsFOnnSprTrylhjnhC3ko=';var plainText = 'id_card=1121321121321321中文2123123&partner_id=TLHS2020001';console.log('加密前', plainText);var encryptPub = new JSEncrypt({default_key_size: 2048});encryptPub.setPublicKey(pubKey);var encryptedPub = encryptPub.encrypt(plainText);console.log('公钥加密后', encryptedPub);var decryptPri = new JSEncrypt({default_key_size: 2048});decryptPri.setPrivateKey(priKey);var uncryptedPri = decryptPri.decrypt(encryptedPub);console.log('私钥解密后', uncryptedPri);
})();
说在最后
Java 和 Javascript 支持的生成密钥对签名加密解密功能可以通用。
相关文章:
RSA签名加密解密
目录Java 接口RSAUtils.java示例中的依赖生成密钥对示例签名示例验证签名示例加密和解密示例Javascript 接口引入依赖生成密钥对示例签名示例验证签名示例加密和解密示例说在最后Java 接口 支持的密钥长度包括4种 RSA512、RSA1024、RSA2048、RSA4096支持的签名算法包括7种 MD2…...
【C语言】数据的存储
☃️内容专栏:【C语言】进阶部分 ☃️本文概括: C语言中的数据类型及其存储方式。 ☃️本文作者:花香碟自来_ ☃️发布时间:2023.2.24 目录 一、数据类型详细介绍 1.1 基本的数据类型 1.2 整型家族 1.3 构造类型 1.4 指针类型…...
「RISC-V Arch」SBI 规范解读(上)
术语 SBI,Supervisor Binary Interface,管理二进制接口 U-Mode,User mode,用户模式 S-Mode,Supervisor mode,监督模式 VS-Mode,Virtualization Supervisor mode,虚拟机监督模式 …...
2023年全国最新二级建造师精选真题及答案5
百分百题库提供二级建造师考试试题、二建考试预测题、二级建造师考试真题、二建证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 51.下列国有资金占控股或者主导地位的依法必须进行招标的项目,可以采取邀请招标的…...
365智能云打印怎么样?365小票无线订单打印机好用吗?
365智能云打印怎么样?365智能云打印是有赞官方首推的订单小票打印机,荣获2016年有赞最佳硬件服务商。可以实现远程云打印,无需连接电脑,只需通过GPRS流量或者WIFI即可连接,不受地理位置和距离限制。365小票无线订单打印…...
细说react源码中的合成事件
最近在做一个功能,然后不小心踩到了 React 合成事件 的坑,好奇心的驱使,去看了 React 官网合成事件 的解释,这不看不知道,一看吓一跳… SyntheticEvent是个什么鬼?咋冒出来了个事件池? 我就一…...
【架构师】零基础到精通——架构演进
博客昵称:架构师Cool 最喜欢的座右铭:一以贯之的努力,不得懈怠的人生。 作者简介:一名Coder,软件设计师/鸿蒙高级工程师认证,在备战高级架构师/系统分析师,欢迎关注小弟! 博主小留言…...
Hadoop命令大全
HDFS分布式文件系统 , 将一个大的文件拆分成多个小文件存储在多台服务器中 文件系统: 目录结构(树状结构) "/" 树根, 目录结构在namenode中维护 目录 1.查看当前目录 2.创建多级目录 3.上传文件 4.查…...
一文带你快速初步了解云计算与大数据
目录 🔍一、云计算基础 1、云计算的概念、特点、关键技术 2、云计算的分类 3、云计算的部署模式 4、云计算的服务模式:IaaS、PaaS、SaaS分别是什么,具体含义要清楚 5、物联网的概念 6、物联网和云计算、大数据的关系 7、了解云计算的…...
STM32 OTA应用开发——通过USB实现OTA升级
STM32 OTA应用开发——通过USB实现OTA升级 目录STM32 OTA应用开发——通过USB实现OTA升级前言1 环境搭建2 功能描述3 BootLoader的制作4 APP的制作5 烧录下载配置6 运行测试结束语前言 什么是OTA? 百度百科:空中下载技术(Over-the-Air Techn…...
JavaScript高级程序设计读书分享之6章——6.2Array
JavaScript高级程序设计(第4版)读书分享笔记记录 适用于刚入门前端的同志 除了 Object,Array 应该就是 ECMAScript 中最常用的类型了。 创建数组 使用 Array 构造函数 在使用 Array 构造函数时,也可以省略 new 操作符。 let colors new Array() let …...
MySQL递归查询 三种实现方式
1 建表脚本1.1 建表DROP TABLE IF EXISTS sys_region; CREATE TABLE sys_region (id int(50) NOT NULL AUTO_INCREMENT COMMENT 地区主键编号,name varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 地区名称,short_name varchar(50) CHARA…...
Servle笔记(7):过滤器
1、过滤器的作用与目的 过滤器的目的 在客户端的请求访问后端资源之前,拦截请求在服务器的响应发送回客户端之前,处理响应 2、过滤器的类型 身份验证过滤器(Authentication Filters)数据压缩过滤器(Data compressio…...
2023年:我成了半个外包
边线业务与主线角色被困外包; 012022年,最后一个工作日,裁员的小刀再次挥下; 商务区楼下又多了几个落寞的身影,办公室内又多了几头暴躁的灵魂; 随着裁员的结束,部门的人员结构简化到了极致&am…...
HTTP中GET与POST方法的区别
1. HTTP HTTP即超文本传输协议(Hyper Text Transfer Protocol),是因特网上应用最广的一种协议。 设计目的:保证客户端与服务器之间的通信(发布和接受HTML页面);工作方式:客户端-服务器端的请求-应答协议 …...
使用ChatGPT需要避免的8个错误
如果ChatGPT是未来世界为每个登上新大陆人发放的一把AK47, 那么现在大多数人做的事,就是突突突一阵扫射, 不管也不知道有没有扫射到自己想要的目标。每个人都在使用 ChatGPT。但几乎每个人都停留在新手模式。 避免下面常见的8个ChatGPT的错…...
ELK日志分析--Kibana
Kibana 概述 部署安装浏览页面并使用 1.Kibana 概述 Kibana-是进入Elastic的窗口使用Kibana,可以 1 搜索,观察和保护。 从发现文档到分析日志再到发现安全漏洞,Kibana是您访问这些功能及其他功能的门户。 2 可视化和分析您的数据。 搜索隐藏的…...
PPP点到点协议认证之PAP认证
PPP点到点协议认证之PAP认证 需求 如图配置接口的IP地址将R1配置为认证端,用户名和密码是 huawei/hcie ,使用的认证方式是pap确保R1和R2之间可以互相ping通 拓扑图 配置思路 确保接口使用协议是PPP确保接口的IP地址配置正确在R1 的端口上,…...
设计模式之建造者模式(C++)
作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 一、建造者模式是什么? 建造者模式是一种创建型的软件设计模式,用于构造相对复杂的对象。 建造者模式可以…...
linux常见的系统日志
我们了解一下常见的系统日志,知道哪些需要收集 1. /var/log/boot.log linux中/var/log/boot.log是系统启动时的日志,其包括自启动服务。 2. /var/log/btmp linux中/var/log/btmp是记录登录失败信息的日志,是一种非文本文件,可以使…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...
微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...
Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「storms…...
从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...
Chrome 浏览器前端与客户端双向通信实战
Chrome 前端(即页面 JS / Web UI)与客户端(C 后端)的交互机制,是 Chromium 架构中非常核心的一环。下面我将按常见场景,从通道、流程、技术栈几个角度做一套完整的分析,特别适合你这种在分析和改…...
