当前位置:   article > 正文

java 实现 国密sm2、sm3 + vue 加密_sm2加密java和vue

sm2加密java和vue

后端:公共类,生成sm2公私钥 ,sm2解密方法,并集成sm2加密、sm3加密

  1. public class SM2Utils {
  2. private static final Logger LOGGER = LoggerFactory.getLogger(SM2Utils.class);
  3. private static final String publicKeyName = "PUBLICKEY";
  4. private static final String privateKeyName = "PRIVATEKEY";
  5. private static final String ENCODING = "UTF-8";
  6. // 生成随机秘钥对
  7. public static Map<String, String> generateKeyPair() {
  8. SM2 sm2 = SM2.Instance();
  9. AsymmetricCipherKeyPair key = null;
  10. while (true) {
  11. key = sm2.ecc_key_pair_generator.generateKeyPair();
  12. if (((ECPrivateKeyParameters) key.getPrivate()).getD().toByteArray().length == 32) {
  13. break;
  14. }
  15. }
  16. ECPrivateKeyParameters ecpriv = (ECPrivateKeyParameters) key.getPrivate();
  17. ECPublicKeyParameters ecpub = (ECPublicKeyParameters) key.getPublic();
  18. BigInteger privateKey = ecpriv.getD();
  19. ECPoint publicKey = ecpub.getQ();
  20. String pubk = Util.byteToHex(publicKey.getEncoded());
  21. String prik = Util.byteToHex(privateKey.toByteArray());
  22. System.out.println("公钥: " + pubk);
  23. System.out.println("私钥: " + prik);
  24. Map<String, String> result = new HashMap<>();
  25. result.put(publicKeyName, pubk);
  26. result.put(privateKeyName, prik);
  27. return result;
  28. }
  29. // 数据加密
  30. public static String encrypt(byte[] publicKey, byte[] data) throws IOException {
  31. if (publicKey == null || publicKey.length == 0) {
  32. return null;
  33. }
  34. if (data == null || data.length == 0) {
  35. return null;
  36. }
  37. byte[] source = new byte[data.length];
  38. System.arraycopy(data, 0, source, 0, data.length);
  39. Cipher cipher = new Cipher();
  40. SM2 sm2 = SM2.Instance();
  41. ECPoint userKey = sm2.ecc_curve.decodePoint(publicKey);
  42. ECPoint c1 = cipher.Init_enc(sm2, userKey);
  43. cipher.Encrypt(source);
  44. byte[] c3 = new byte[32];
  45. cipher.Dofinal(c3);
  46. return new StringBuffer(Util.byteToHex(c1.getEncoded())).append(Util.byteToHex(c3)).append(Util.byteToHex(source)).toString();
  47. }
  48. // 数据解密
  49. public static byte[] decrypt(byte[] privateKey, byte[] encryptedData) throws IOException {
  50. if (privateKey == null || privateKey.length == 0) {
  51. return null;
  52. }
  53. if (encryptedData == null || encryptedData.length == 0) {
  54. return null;
  55. }
  56. // 加密字节数组转换为十六进制的字符串 长度变为encryptedData.length * 2
  57. String data = Util.byteToHex(encryptedData);
  58. byte[] c1Bytes = Util.hexToByte(data.substring(0, 130));
  59. int c2Len = encryptedData.length - 97;
  60. byte[] c3 = Util.hexToByte(data.substring(130, 130 + 64));
  61. byte[] c2 = Util.hexToByte(data.substring(194, 194 + 2 * c2Len));
  62. SM2 sm2 = SM2.Instance();
  63. BigInteger userD = new BigInteger(1, privateKey);
  64. // 通过C1实体字节来生成ECPoint
  65. ECPoint c1 = sm2.ecc_curve.decodePoint(c1Bytes);
  66. Cipher cipher = new Cipher();
  67. cipher.Init_dec(userD, c1);
  68. cipher.Decrypt(c2);
  69. cipher.Dofinal(c3);
  70. // 返回解密结果
  71. return c2;
  72. }
  73. /**
  74. * sm3算法加密
  75. * @explain
  76. * @param paramStr 待加密字符串
  77. * @param key 密钥
  78. * @return 返回加密后,固定长度=32的16进制字符串
  79. */
  80. public static String sm3EncryptPlus(String paramStr,String key){
  81. // 将返回的hash值转换成16进制字符串
  82. String resultHexString = "";
  83. try {
  84. // 将字符串转换成byte数组
  85. byte[] srcData = paramStr.getBytes(ENCODING);
  86. // 调用hash()
  87. byte[] resultHash = hmac(srcData,key.getBytes(ENCODING));
  88. // 将返回的hash值转换成16进制字符串
  89. resultHexString = ByteUtils.toHexString(resultHash);
  90. } catch (UnsupportedEncodingException e) {
  91. e.printStackTrace();
  92. }
  93. return resultHexString;
  94. }
  95. /**
  96. * 通过密钥进行加密
  97. * @explain 指定密钥进行加密
  98. * @param key 密钥
  99. * @param srcData 被加密的byte数组
  100. * @return
  101. */
  102. public static byte[] hmac(byte[] key, byte[] srcData) {
  103. KeyParameter keyParameter = new KeyParameter(key);
  104. SM3Digest digest = new SM3Digest();
  105. HMac mac = new HMac(digest);
  106. mac.init(keyParameter);
  107. mac.update(srcData, 0, srcData.length);
  108. byte[] result = new byte[mac.getMacSize()];
  109. mac.doFinal(result, 0);
  110. return result;
  111. }
  112. /**
  113. * sm3算法加密
  114. * @explain
  115. * @param paramStr 待加密字符串
  116. * @return 返回加密后,固定长度=32的16进制字符串
  117. */
  118. public static String sm3Encrypt(String paramStr){
  119. // 将返回的hash值转换成16进制字符串
  120. String resultHexString = "";
  121. try {
  122. // 将字符串转换成byte数组
  123. byte[] srcData = paramStr.getBytes(ENCODING);
  124. // 调用hash()
  125. byte[] resultHash = hash(srcData);
  126. // 将返回的hash值转换成16进制字符串
  127. resultHexString = ByteUtils.toHexString(resultHash);
  128. } catch (UnsupportedEncodingException e) {
  129. e.printStackTrace();
  130. }
  131. return resultHexString;
  132. }
  133. /**
  134. * 返回长度=32的byte数组
  135. * @explain 生成对应的hash值
  136. * @param srcData
  137. * @return
  138. */
  139. public static byte[] hash(byte[] srcData) {
  140. SM3Digest digest = new SM3Digest();
  141. digest.update(srcData, 0, srcData.length);
  142. byte[] hash = new byte[digest.getDigestSize()];
  143. digest.doFinal(hash, 0);
  144. return hash;
  145. }
  146. }

与之关联的工具类有:Util 、Cipher 、SM2

  1. public class Cipher {
  2. private int ct;
  3. private ECPoint p2;
  4. private SM3Digest sm3keybase;
  5. private SM3Digest sm3c3;
  6. private byte key[];
  7. private byte keyOff;
  8. public Cipher()
  9. {
  10. this.ct = 1;
  11. this.key = new byte[32];
  12. this.keyOff = 0;
  13. }
  14. private void Reset()
  15. {
  16. this.sm3keybase = new SM3Digest();
  17. this.sm3c3 = new SM3Digest();
  18. byte p[] = Util.byteConvert32Bytes(p2.getX().toBigInteger());
  19. this.sm3keybase.update(p, 0, p.length);
  20. this.sm3c3.update(p, 0, p.length);
  21. p = Util.byteConvert32Bytes(p2.getY().toBigInteger());
  22. this.sm3keybase.update(p, 0, p.length);
  23. this.ct = 1;
  24. NextKey();
  25. }
  26. private void NextKey()
  27. {
  28. SM3Digest sm3keycur = new SM3Digest(this.sm3keybase);
  29. sm3keycur.update((byte) (ct >> 24 & 0xff));
  30. sm3keycur.update((byte) (ct >> 16 & 0xff));
  31. sm3keycur.update((byte) (ct >> 8 & 0xff));
  32. sm3keycur.update((byte) (ct & 0xff));
  33. sm3keycur.doFinal(key, 0);
  34. this.keyOff = 0;
  35. this.ct++;
  36. }
  37. public ECPoint Init_enc(SM2 sm2, ECPoint userKey)
  38. {
  39. AsymmetricCipherKeyPair key = sm2.ecc_key_pair_generator.generateKeyPair();
  40. ECPrivateKeyParameters ecpriv = (ECPrivateKeyParameters) key.getPrivate();
  41. ECPublicKeyParameters ecpub = (ECPublicKeyParameters) key.getPublic();
  42. BigInteger k = ecpriv.getD();
  43. ECPoint c1 = ecpub.getQ();
  44. this.p2 = userKey.multiply(k);
  45. Reset();
  46. return c1;
  47. }
  48. public void Encrypt(byte data[])
  49. {
  50. this.sm3c3.update(data, 0, data.length);
  51. for (int i = 0; i < data.length; i++)
  52. {
  53. if (keyOff == key.length)
  54. {
  55. NextKey();
  56. }
  57. data[i] ^= key[keyOff++];
  58. }
  59. }
  60. public void Init_dec(BigInteger userD, ECPoint c1)
  61. {
  62. this.p2 = c1.multiply(userD);
  63. Reset();
  64. }
  65. public void Decrypt(byte data[])
  66. {
  67. for (int i = 0; i < data.length; i++)
  68. {
  69. if (keyOff == key.length)
  70. {
  71. NextKey();
  72. }
  73. data[i] ^= key[keyOff++];
  74. }
  75. this.sm3c3.update(data, 0, data.length);
  76. }
  77. public void Dofinal(byte c3[])
  78. {
  79. byte p[] = Util.byteConvert32Bytes(p2.getY().toBigInteger());
  80. this.sm3c3.update(p, 0, p.length);
  81. this.sm3c3.doFinal(c3, 0);
  82. Reset();
  83. }
  84. }
  85. public class SM2 {
  86. //正式参数
  87. public static String[] ecc_param = {
  88. "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF",
  89. "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC",
  90. "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93",
  91. "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123",
  92. "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7",
  93. "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0"
  94. };
  95. public static SM2 Instance() {
  96. return new SM2();
  97. }
  98. /** 素数p */
  99. public final BigInteger ecc_p;
  100. /** 系数a */
  101. public final BigInteger ecc_a;
  102. /** 系数b */
  103. public final BigInteger ecc_b;
  104. /** 基点G, G=(xg,yg),其介记为n */
  105. public final BigInteger ecc_n;
  106. /** 坐标x */
  107. public final BigInteger ecc_gx;
  108. /** 坐标y */
  109. public final BigInteger ecc_gy;
  110. public final ECCurve ecc_curve;
  111. public final ECPoint ecc_point_g;
  112. public final ECDomainParameters ecc_bc_spec;
  113. public final ECKeyPairGenerator ecc_key_pair_generator;
  114. public final ECFieldElement ecc_gx_fieldelement;
  115. public final ECFieldElement ecc_gy_fieldelement;
  116. public SM2() {
  117. this.ecc_p = new BigInteger(ecc_param[0], 16);
  118. this.ecc_a = new BigInteger(ecc_param[1], 16);
  119. this.ecc_b = new BigInteger(ecc_param[2], 16);
  120. this.ecc_n = new BigInteger(ecc_param[3], 16);
  121. this.ecc_gx = new BigInteger(ecc_param[4], 16);
  122. this.ecc_gy = new BigInteger(ecc_param[5], 16);
  123. this.ecc_gx_fieldelement = new ECFieldElement.Fp(this.ecc_p, this.ecc_gx);
  124. this.ecc_gy_fieldelement = new ECFieldElement.Fp(this.ecc_p, this.ecc_gy);
  125. this.ecc_curve = new ECCurve.Fp(this.ecc_p, this.ecc_a, this.ecc_b);
  126. this.ecc_point_g = new ECPoint.Fp(this.ecc_curve, this.ecc_gx_fieldelement, this.ecc_gy_fieldelement);
  127. this.ecc_bc_spec = new ECDomainParameters(this.ecc_curve, this.ecc_point_g, this.ecc_n);
  128. ECKeyGenerationParameters ecc_ecgenparam;
  129. ecc_ecgenparam = new ECKeyGenerationParameters(this.ecc_bc_spec, new SecureRandom());
  130. this.ecc_key_pair_generator = new ECKeyPairGenerator();
  131. this.ecc_key_pair_generator.init(ecc_ecgenparam);
  132. }
  133. }
  134. public class Util {
  135. /**
  136. * 整形转换成网络传输的字节流(字节数组)型数据
  137. *
  138. * @param num 一个整型数据
  139. * @return 4个字节的自己数组
  140. */
  141. public static byte[] intToBytes(int num) {
  142. byte[] bytes = new byte[4];
  143. bytes[0] = (byte) (0xff & (num >> 0));
  144. bytes[1] = (byte) (0xff & (num >> 8));
  145. bytes[2] = (byte) (0xff & (num >> 16));
  146. bytes[3] = (byte) (0xff & (num >> 24));
  147. return bytes;
  148. }
  149. /**
  150. * 四个字节的字节数据转换成一个整形数据
  151. *
  152. * @param bytes 4个字节的字节数组
  153. * @return 一个整型数据
  154. */
  155. public static int byteToInt(byte[] bytes) {
  156. int num = 0;
  157. int temp;
  158. temp = (0x000000ff & (bytes[0])) << 0;
  159. num = num | temp;
  160. temp = (0x000000ff & (bytes[1])) << 8;
  161. num = num | temp;
  162. temp = (0x000000ff & (bytes[2])) << 16;
  163. num = num | temp;
  164. temp = (0x000000ff & (bytes[3])) << 24;
  165. num = num | temp;
  166. return num;
  167. }
  168. /**
  169. * 长整形转换成网络传输的字节流(字节数组)型数据
  170. *
  171. * @param num 一个长整型数据
  172. * @return 4个字节的自己数组
  173. */
  174. public static byte[] longToBytes(long num) {
  175. byte[] bytes = new byte[8];
  176. for (int i = 0; i < 8; i++) {
  177. bytes[i] = (byte) (0xff & (num >> (i * 8)));
  178. }
  179. return bytes;
  180. }
  181. /**
  182. * 大数字转换字节流(字节数组)型数据
  183. *
  184. * @param n
  185. * @return
  186. */
  187. public static byte[] byteConvert32Bytes(BigInteger n) {
  188. byte tmpd[] = (byte[]) null;
  189. if (n == null) {
  190. return null;
  191. }
  192. if (n.toByteArray().length == 33) {
  193. tmpd = new byte[32];
  194. System.arraycopy(n.toByteArray(), 1, tmpd, 0, 32);
  195. } else if (n.toByteArray().length == 32) {
  196. tmpd = n.toByteArray();
  197. } else {
  198. tmpd = new byte[32];
  199. for (int i = 0; i < 32 - n.toByteArray().length; i++) {
  200. tmpd[i] = 0;
  201. }
  202. System.arraycopy(n.toByteArray(), 0, tmpd, 32 - n.toByteArray().length, n.toByteArray().length);
  203. }
  204. return tmpd;
  205. }
  206. /**
  207. * 换字节流(字节数组)型数据转大数字
  208. *
  209. * @param b
  210. * @return
  211. */
  212. public static BigInteger byteConvertInteger(byte[] b) {
  213. if (b[0] < 0) {
  214. byte[] temp = new byte[b.length + 1];
  215. temp[0] = 0;
  216. System.arraycopy(b, 0, temp, 1, b.length);
  217. return new BigInteger(temp);
  218. }
  219. return new BigInteger(b);
  220. }
  221. /**
  222. * 根据字节数组获得值(十六进制数字)
  223. *
  224. * @param bytes
  225. * @return
  226. */
  227. public static String getHexString(byte[] bytes) {
  228. return getHexString(bytes, true);
  229. }
  230. /**
  231. * 根据字节数组获得值(十六进制数字)
  232. *
  233. * @param bytes
  234. * @param upperCase
  235. * @return
  236. */
  237. public static String getHexString(byte[] bytes, boolean upperCase) {
  238. String ret = "";
  239. for (int i = 0; i < bytes.length; i++) {
  240. ret += Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1);
  241. }
  242. return upperCase ? ret.toUpperCase() : ret;
  243. }
  244. /**
  245. * 打印十六进制字符串
  246. *
  247. * @param bytes
  248. */
  249. public static void printHexString(byte[] bytes) {
  250. for (int i = 0; i < bytes.length; i++) {
  251. String hex = Integer.toHexString(bytes[i] & 0xFF);
  252. if (hex.length() == 1) {
  253. hex = '0' + hex;
  254. }
  255. System.out.print("0x" + hex.toUpperCase() + ",");
  256. }
  257. System.out.println("");
  258. }
  259. /**
  260. * Convert hex string to byte[]
  261. *
  262. * @param hexString the hex string
  263. * @return byte[]
  264. */
  265. public static byte[] hexStringToBytes(String hexString) {
  266. if (hexString == null || hexString.equals("")) {
  267. return null;
  268. }
  269. hexString = hexString.toUpperCase();
  270. int length = hexString.length() / 2;
  271. char[] hexChars = hexString.toCharArray();
  272. byte[] d = new byte[length];
  273. for (int i = 0; i < length; i++) {
  274. int pos = i * 2;
  275. d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
  276. }
  277. return d;
  278. }
  279. /**
  280. * Convert char to byte
  281. *
  282. * @param c char
  283. * @return byte
  284. */
  285. public static byte charToByte(char c) {
  286. return (byte) "0123456789ABCDEF".indexOf(c);
  287. }
  288. /**
  289. * 用于建立十六进制字符的输出的小写字符数组
  290. */
  291. private static final char[] DIGITS_LOWER = {'0', '1', '2', '3', '4', '5',
  292. '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
  293. /**
  294. * 用于建立十六进制字符的输出的大写字符数组
  295. */
  296. private static final char[] DIGITS_UPPER = {'0', '1', '2', '3', '4', '5',
  297. '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
  298. /**
  299. * 将字节数组转换为十六进制字符数组
  300. *
  301. * @param data byte[]
  302. * @return 十六进制char[]
  303. */
  304. public static char[] encodeHex(byte[] data) {
  305. return encodeHex(data, true);
  306. }
  307. /**
  308. * 将字节数组转换为十六进制字符数组
  309. *
  310. * @param data byte[]
  311. * @param toLowerCase <code>true</code> 传换成小写格式 , <code>false</code> 传换成大写格式
  312. * @return 十六进制char[]
  313. */
  314. public static char[] encodeHex(byte[] data, boolean toLowerCase) {
  315. return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
  316. }
  317. /**
  318. * 将字节数组转换为十六进制字符数组
  319. *
  320. * @param data byte[]
  321. * @param toDigits 用于控制输出的char[]
  322. * @return 十六进制char[]
  323. */
  324. protected static char[] encodeHex(byte[] data, char[] toDigits) {
  325. int l = data.length;
  326. char[] out = new char[l << 1];
  327. // two characters form the hex value.
  328. for (int i = 0, j = 0; i < l; i++) {
  329. out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
  330. out[j++] = toDigits[0x0F & data[i]];
  331. }
  332. return out;
  333. }
  334. /**
  335. * 将字节数组转换为十六进制字符串
  336. *
  337. * @param data byte[]
  338. * @return 十六进制String
  339. */
  340. public static String encodeHexString(byte[] data) {
  341. return encodeHexString(data, true);
  342. }
  343. /**
  344. * 将字节数组转换为十六进制字符串
  345. *
  346. * @param data byte[]
  347. * @param toLowerCase <code>true</code> 传换成小写格式 , <code>false</code> 传换成大写格式
  348. * @return 十六进制String
  349. */
  350. public static String encodeHexString(byte[] data, boolean toLowerCase) {
  351. return encodeHexString(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
  352. }
  353. /**
  354. * 将字节数组转换为十六进制字符串
  355. *
  356. * @param data byte[]
  357. * @param toDigits 用于控制输出的char[]
  358. * @return 十六进制String
  359. */
  360. protected static String encodeHexString(byte[] data, char[] toDigits) {
  361. return new String(encodeHex(data, toDigits));
  362. }
  363. /**
  364. * 将十六进制字符数组转换为字节数组
  365. *
  366. * @param data 十六进制char[]
  367. * @return byte[]
  368. * @throws RuntimeException 如果源十六进制字符数组是一个奇怪的长度,将抛出运行时异常
  369. */
  370. public static byte[] decodeHex(char[] data) {
  371. int len = data.length;
  372. if ((len & 0x01) != 0) {
  373. throw new RuntimeException("Odd number of characters.");
  374. }
  375. byte[] out = new byte[len >> 1];
  376. // two characters form the hex value.
  377. for (int i = 0, j = 0; j < len; i++) {
  378. int f = toDigit(data[j], j) << 4;
  379. j++;
  380. f = f | toDigit(data[j], j);
  381. j++;
  382. out[i] = (byte) (f & 0xFF);
  383. }
  384. return out;
  385. }
  386. /**
  387. * 将十六进制字符转换成一个整数
  388. *
  389. * @param ch 十六进制char
  390. * @param index 十六进制字符在字符数组中的位置
  391. * @return 一个整数
  392. * @throws RuntimeException 当ch不是一个合法的十六进制字符时,抛出运行时异常
  393. */
  394. protected static int toDigit(char ch, int index) {
  395. int digit = Character.digit(ch, 16);
  396. if (digit == -1) {
  397. throw new RuntimeException("Illegal hexadecimal character " + ch
  398. + " at index " + index);
  399. }
  400. return digit;
  401. }
  402. /**
  403. * 数字字符串转ASCII码字符串
  404. *
  405. * @param content 字符串
  406. * @return ASCII字符串
  407. */
  408. public static String StringToAsciiString(String content) {
  409. String result = "";
  410. int max = content.length();
  411. for (int i = 0; i < max; i++) {
  412. char c = content.charAt(i);
  413. String b = Integer.toHexString(c);
  414. result = result + b;
  415. }
  416. return result;
  417. }
  418. /**
  419. * 十六进制转字符串
  420. *
  421. * @param hexString 十六进制字符串
  422. * @param encodeType 编码类型4:Unicode,2:普通编码
  423. * @return 字符串
  424. */
  425. public static String hexStringToString(String hexString, int encodeType) {
  426. String result = "";
  427. int max = hexString.length() / encodeType;
  428. for (int i = 0; i < max; i++) {
  429. char c = (char) hexStringToAlgorism(hexString
  430. .substring(i * encodeType, (i + 1) * encodeType));
  431. result += c;
  432. }
  433. return result;
  434. }
  435. /**
  436. * 十六进制字符串装十进制
  437. *
  438. * @param hex 十六进制字符串
  439. * @return 十进制数值
  440. */
  441. public static int hexStringToAlgorism(String hex) {
  442. hex = hex.toUpperCase();
  443. int max = hex.length();
  444. int result = 0;
  445. for (int i = max; i > 0; i--) {
  446. char c = hex.charAt(i - 1);
  447. int algorism = 0;
  448. if (c >= '0' && c <= '9') {
  449. algorism = c - '0';
  450. } else {
  451. algorism = c - 55;
  452. }
  453. result += Math.pow(16, max - i) * algorism;
  454. }
  455. return result;
  456. }
  457. /**
  458. * 十六转二进制
  459. *
  460. * @param hex 十六进制字符串
  461. * @return 二进制字符串
  462. */
  463. public static String hexStringToBinary(String hex) {
  464. hex = hex.toUpperCase();
  465. String result = "";
  466. int max = hex.length();
  467. for (int i = 0; i < max; i++) {
  468. char c = hex.charAt(i);
  469. switch (c) {
  470. case '0':
  471. result += "0000";
  472. break;
  473. case '1':
  474. result += "0001";
  475. break;
  476. case '2':
  477. result += "0010";
  478. break;
  479. case '3':
  480. result += "0011";
  481. break;
  482. case '4':
  483. result += "0100";
  484. break;
  485. case '5':
  486. result += "0101";
  487. break;
  488. case '6':
  489. result += "0110";
  490. break;
  491. case '7':
  492. result += "0111";
  493. break;
  494. case '8':
  495. result += "1000";
  496. break;
  497. case '9':
  498. result += "1001";
  499. break;
  500. case 'A':
  501. result += "1010";
  502. break;
  503. case 'B':
  504. result += "1011";
  505. break;
  506. case 'C':
  507. result += "1100";
  508. break;
  509. case 'D':
  510. result += "1101";
  511. break;
  512. case 'E':
  513. result += "1110";
  514. break;
  515. case 'F':
  516. result += "1111";
  517. break;
  518. }
  519. }
  520. return result;
  521. }
  522. /**
  523. * ASCII码字符串转数字字符串
  524. *
  525. * @param content ASCII字符串
  526. * @return 字符串
  527. */
  528. public static String AsciiStringToString(String content) {
  529. String result = "";
  530. int length = content.length() / 2;
  531. for (int i = 0; i < length; i++) {
  532. String c = content.substring(i * 2, i * 2 + 2);
  533. int a = hexStringToAlgorism(c);
  534. char b = (char) a;
  535. String d = String.valueOf(b);
  536. result += d;
  537. }
  538. return result;
  539. }
  540. /**
  541. * 将十进制转换为指定长度的十六进制字符串
  542. *
  543. * @param algorism int 十进制数字
  544. * @param maxLength int 转换后的十六进制字符串长度
  545. * @return String 转换后的十六进制字符串
  546. */
  547. public static String algorismToHexString(int algorism, int maxLength) {
  548. String result = "";
  549. result = Integer.toHexString(algorism);
  550. if (result.length() % 2 == 1) {
  551. result = "0" + result;
  552. }
  553. return patchHexString(result.toUpperCase(), maxLength);
  554. }
  555. /**
  556. * 字节数组转为普通字符串(ASCII对应的字符)
  557. *
  558. * @param bytearray byte[]
  559. * @return String
  560. */
  561. public static String byteToString(byte[] bytearray) {
  562. String result = "";
  563. char temp;
  564. int length = bytearray.length;
  565. for (int i = 0; i < length; i++) {
  566. temp = (char) bytearray[i];
  567. result += temp;
  568. }
  569. return result;
  570. }
  571. /**
  572. * 二进制字符串转十进制
  573. *
  574. * @param binary 二进制字符串
  575. * @return 十进制数值
  576. */
  577. public static int binaryToAlgorism(String binary) {
  578. int max = binary.length();
  579. int result = 0;
  580. for (int i = max; i > 0; i--) {
  581. char c = binary.charAt(i - 1);
  582. int algorism = c - '0';
  583. result += Math.pow(2, max - i) * algorism;
  584. }
  585. return result;
  586. }
  587. /**
  588. * 十进制转换为十六进制字符串
  589. *
  590. * @param algorism int 十进制的数字
  591. * @return String 对应的十六进制字符串
  592. */
  593. public static String algorismToHEXString(int algorism) {
  594. String result = "";
  595. result = Integer.toHexString(algorism);
  596. if (result.length() % 2 == 1) {
  597. result = "0" + result;
  598. }
  599. result = result.toUpperCase();
  600. return result;
  601. }
  602. /**
  603. * HEX字符串前补0,主要用于长度位数不足。
  604. *
  605. * @param str String 需要补充长度的十六进制字符串
  606. * @param maxLength int 补充后十六进制字符串的长度
  607. * @return 补充结果
  608. */
  609. static public String patchHexString(String str, int maxLength) {
  610. String temp = "";
  611. for (int i = 0; i < maxLength - str.length(); i++) {
  612. temp = "0" + temp;
  613. }
  614. str = (temp + str).substring(0, maxLength);
  615. return str;
  616. }
  617. /**
  618. * 将一个字符串转换为int
  619. *
  620. * @param s String 要转换的字符串
  621. * @param defaultInt int 如果出现异常,默认返回的数字
  622. * @param radix int 要转换的字符串是什么进制的,如16 8 10.
  623. * @return int 转换后的数字
  624. */
  625. public static int parseToInt(String s, int defaultInt, int radix) {
  626. int i = 0;
  627. try {
  628. i = Integer.parseInt(s, radix);
  629. } catch (NumberFormatException ex) {
  630. i = defaultInt;
  631. }
  632. return i;
  633. }
  634. /**
  635. * 将一个十进制形式的数字字符串转换为int
  636. *
  637. * @param s String 要转换的字符串
  638. * @param defaultInt int 如果出现异常,默认返回的数字
  639. * @return int 转换后的数字
  640. */
  641. public static int parseToInt(String s, int defaultInt) {
  642. int i = 0;
  643. try {
  644. i = Integer.parseInt(s);
  645. } catch (NumberFormatException ex) {
  646. i = defaultInt;
  647. }
  648. return i;
  649. }
  650. /**
  651. * 十六进制串转化为byte数组
  652. *
  653. * @return the array of byte
  654. */
  655. public static byte[] hexToByte(String hex)
  656. throws IllegalArgumentException {
  657. if (hex.length() % 2 != 0) {
  658. throw new IllegalArgumentException();
  659. }
  660. if (hex.length() < 1) {
  661. return null;
  662. } else {
  663. byte[] result = new byte[hex.length() / 2];
  664. int j = 0;
  665. for(int i = 0; i < hex.length(); i+=2) {
  666. result[j++] = (byte)Integer.parseInt(hex.substring(i,i+2), 16);
  667. }
  668. return result;
  669. }
  670. }
  671. /**
  672. * 字节数组转换为十六进制字符串
  673. *
  674. * @param b byte[] 需要转换的字节数组
  675. * @return String 十六进制字符串
  676. */
  677. public static String byteToHex(byte b[]) {
  678. if (b == null) {
  679. return "";
  680. }
  681. StringBuffer sb = new StringBuffer();
  682. for(int i = 0; i < b.length; i++) {
  683. String hex = Integer.toHexString(b[i] & 0xFF);
  684. if(hex.length() < 2) {
  685. hex = "0" + hex;
  686. }
  687. sb.append(hex.toUpperCase());
  688. }
  689. return sb.toString();
  690. }
  691. public static byte[] subByte(byte[] input, int startIndex, int length) {
  692. byte[] bt = new byte[length];
  693. for (int i = 0; i < length; i++) {
  694. bt[i] = input[i + startIndex];
  695. }
  696. return bt;
  697. }
  698. }

获取秘钥对,并对私钥保存,公钥返回给前端

  1. public ResponseData getSmPublicCode() {
  2. Map<String, String> result = new HashMap<>();
  3. String publicKry = "";
  4. if(ObjectUtil.isNull(redisTemplate.opsForValue().get(SMPublicPrivate.SM_PUBLIC.getValue()))){
  5. // 1. 获取公私钥对
  6. Map<String, String> map = SM2Utils.generateKeyPair();
  7. redisTemplate.opsForValue().set(SMPublicPrivate.SM_PRIVATE.getValue(),map.get(privateKeyName));
  8. redisTemplate.opsForValue().set(SMPublicPrivate.SM_PUBLIC.getValue(),map.get(publicKeyName));
  9. publicKry = map.get(publicKeyName);
  10. }else{
  11. publicKry = (String) redisTemplate.opsForValue().get(SMPublicPrivate.SM_PUBLIC.getValue());
  12. }
  13. result.put("pubKey",publicKry);
  14. return ResponseData.success(result);
  15. }

前端:vue js端加密(使用sm-crypto)

通过引入sm-crypto.js,然后利用doEncrypt方法进行加密,参数为:明文密码、后端生成的公钥、加密方式

  1. encryption() {
  2. const sm2 = require('sm-crypto').sm2
  3. const cipherMode = 1 ;// 1 - C1C3C2,0 - C1C2C3,默认为1
  4. alert(this.loginForm.password)
  5. let encryptData = sm2.doEncrypt(this.loginForm.password, this.smPublicCode, cipherMode ) // 加密结果
  6. return '04' + encryptData;
  7. },

返回的密码密文需要拼接 “04”,避免后端因乱码解密失败

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/50031
推荐阅读
相关标签
  

闽ICP备14008679号