当前位置:   article > 正文

国密算法使用-SM4

sm4

1.概念介绍

SM4:无线局域网标准的分组数据算法。对称加密,密钥长度和分组长度均为128位。

2.算法介绍

此算法是一个分组算法,用于无线局域网产品。该算法的分组长度为128比特,密钥长度为128比特。加密算法与密钥扩展算法都采用32轮非线性迭代结构。解密算法与加密算法的结构相同,只是轮密钥的使用顺序相反,解密轮密钥是加密轮密钥的逆序。

此算法采用非线性迭代结构,每次迭代由一个轮函数给出,其中轮函数由一个非线性变换和线性变换复合而成,非线性变换由S盒所给出。其中rki为轮密钥,合成置换T组成轮函数。轮密钥的产生与上图流程类似,由加密密钥作为输入生成,轮函数中的线性变换不同,还有些参数的区别。

过程:

基本运算:SM4密码算法使用模2加和循环移位作为基本运算。

  基本密码部件:SM4密码算法使用了S盒、非线性变换τ、线性变换部件L、合成变换T基本密码部件。

  轮函数:SM4密码算法采用对基本轮函数进行迭代的结构。利用上述基本密码部件,便可构成轮函数。SM4密码算法的轮函数是一种以字为处理单位的密码函数。

  加密算法:SM4密码算法是一个分组算法。数据分组长度为128比特,密钥长度为128比特。加密算法采用32轮迭代结构,每轮使用一个轮密钥。

  解密算法:SM4密码算法是对合运算,因此解密算法与加密算法的结构相同,只是轮密铝的使用顺序相反,解密轮密钥是加密轮密钥的逆序。

  密钥扩展算法:SM4密码算法使用128位的加密密钥,并采用32轮法代加密结构,每一轮加密使用一个32位的轮密钥,共使用32个轮密钥。因此需要使用密钥扩展算法,从加密密钥产生出32个轮密钥。

  SM4的安全性:SM4密码算法经过我国专业密码机构的充分分析测试,可以抵抗差分攻击、线性攻击等现有攻击,因此是安全的。


3.与DES、AES算法比较

用法上基本一样,只不过密钥变成16字节,加密数据16字节,结果也是16字节。


4.SM4在Java中加密案例

  1. public class Sm4Utils {
  2. // 编码
  3. private static final String ENCODING = "UTF-8";
  4. // 加密名称
  5. public static final String ALGORIGTHM_NAME = "SM4";
  6. // 加密分组方式
  7. public static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS7Padding";
  8. //KEY长度
  9. public static final int DEFAULT_KEY_SIZE = 128;
  10. public Sm4Utils() {
  11. }
  12. static {
  13. Security.addProvider(new BouncyCastleProvider());
  14. }
  15. // 生成ecb暗号
  16. private static Cipher generateEcbCipher(String algorithmName, int mode, byte[] key) throws Exception {
  17. Cipher cipher = Cipher.getInstance(algorithmName,BouncyCastleProvider.PROVIDER_NAME);
  18. Key sm4Key = new SecretKeySpec(key, ALGORIGTHM_NAME);
  19. cipher.init(mode, sm4Key);
  20. return cipher;
  21. }
  22. // 生成密钥
  23. public static byte[] generateKey() throws Exception {
  24. return generateKey(DEFAULT_KEY_SIZE);
  25. }
  26. public static byte[] generateKey(int keySize) throws Exception {
  27. KeyGenerator kg = KeyGenerator.getInstance(ALGORIGTHM_NAME, BouncyCastleProvider.PROVIDER_NAME);
  28. kg.init(keySize, new SecureRandom());
  29. return kg.generateKey().getEncoded();
  30. }
  31. // 加密
  32. public static String encryptEcb(String hexKey, String paramStr, String charset) throws Exception {
  33. String cipherText = "";
  34. if (null != paramStr && !"".equals(paramStr)) {
  35. byte[] keyData = ByteUtils.fromHexString(hexKey);
  36. charset = charset.trim();
  37. if (charset.length() <= 0) {
  38. charset = ENCODING;
  39. }
  40. byte[] srcData = paramStr.getBytes(charset);
  41. byte[] cipherArray = encrypt_Ecb_Padding(keyData, srcData);
  42. cipherText = ByteUtils.toHexString(cipherArray);
  43. }
  44. return cipherText;
  45. }
  46. // 加密模式之ecb
  47. public static byte[] encrypt_Ecb_Padding(byte[] key, byte[] data) throws Exception {
  48. Cipher cipher = generateEcbCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.ENCRYPT_MODE, key);
  49. byte[] bs = cipher.doFinal(data);
  50. return bs;
  51. }
  52. // Sm4解密
  53. public static String decryptEcb(String hexKey, String cipherText, String charset) throws Exception {
  54. String decryptStr = "";
  55. byte[] keyData = ByteUtils.fromHexString(hexKey);
  56. byte[] cipherData = ByteUtils.fromHexString(cipherText);
  57. byte[] srcData = decrypt_Ecb_Padding(keyData, cipherData);
  58. charset = charset.trim();
  59. if (charset.length() <= 0) {
  60. charset = ENCODING;
  61. }
  62. decryptStr = new String(srcData, charset);
  63. return decryptStr;
  64. }
  65. // 解密
  66. public static byte[] decrypt_Ecb_Padding(byte[] key, byte[] cipherText) throws Exception {
  67. Cipher cipher = generateEcbCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.DECRYPT_MODE, key);
  68. return cipher.doFinal(cipherText);
  69. }
  70. // 密码校验
  71. public static boolean verifyEcb(String hexKey,String cipherText,String paramStr) throws Exception {
  72. boolean flag = false;
  73. byte[] keyData = ByteUtils.fromHexString(hexKey);
  74. byte[] cipherData = ByteUtils.fromHexString(cipherText);
  75. byte[] decryptData = decrypt_Ecb_Padding(keyData,cipherData);
  76. byte[] srcData = paramStr.getBytes(ENCODING);
  77. flag = Arrays.equals(decryptData,srcData);
  78. return flag;
  79. }
  80. public static void main(String[] args) {
  81. try {
  82. String json = "{\"name\":\"Devil\"}";
  83. System.out.println("json: " + json);
  84. String key = ByteUtils.toHexString(Sm4Utils.generateKey());
  85. System.out.println("key: " + key);
  86. String encryptJson= Sm4Utils.encryptEcb(key, json,ENCODING);
  87. System.out.println("encryptJson: " + encryptJson);
  88. System.out.println(Sm4Utils.verifyEcb(key, encryptJson, json));
  89. String decryptJson = Sm4Utils.decryptEcb(key, encryptJson,ENCODING);
  90. System.out.println("decryptJson: " + decryptJson);
  91. } catch (Exception e) {
  92. e.printStackTrace();
  93. }
  94. }
  95. }

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

闽ICP备14008679号