SM4算法的ECB模式在java和js中的一些区别

最近项目上遇到一个让我感觉比较困扰的问题,我们提供的用java编写的sm4加密算法计算得到的结果和项目上反馈的js编写的结果不一样。对比代码发现了一个有趣的事情。

java和js的加密步骤及方法几乎是一样的,最后把问题定位在了下面这个方法上:

java:

private long SHL(long x, int n)
	{
		return (x & 0xFFFFFFFF) << n;
	}

javascript:

this.SHL=function(x,n){
            return (x & 0xFFFFFFFF) << n;
     }

这里的返回结果为什么不一致呢,起初我百思不得其解;后来看到这样一篇文章

javascript 数字(Number类型)的范围,整数的范围是多少?_cvper's world !-CSDN博客_javascript number 范围

由于js整形对应的十进制只有16位,所以整数范围是-2^53  ------  2^53   。 所以在& 和<<之后会把长于16位的二进制给截掉。所以sm4算法在这里开始产生分歧。这也就是为什么js和java用sm4加密,结果不一样。

这里可以看一下我在java上的一些处理

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
以下是Java使用SM4算法ECB模式加密的示例代码: ```java import org.bouncycastle.jce.provider.BouncyCastleProvider; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.security.Security; import java.util.Base64; public class SM4Util { private static final String ALGORITHM_NAME = "SM4"; private static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS7Padding"; /** * SM4加密 * * @param key 16位秘钥 * @param data 待加密数据 * @return 加密结果 * @throws Exception */ public static String encryptData_ECB(String key, String data) throws Exception { Security.addProvider(new BouncyCastleProvider()); Cipher cipher = Cipher.getInstance(ALGORITHM_NAME_ECB_PADDING, "BC"); SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), ALGORITHM_NAME); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec); byte[] encrypted = cipher.doFinal(data.getBytes("UTF-8")); return Base64.getEncoder().encodeToString(encrypted); } /** * SM4解密 * * @param key 16位秘钥 * @param cipherText 待解密数据 * @return 解密结果 * @throws Exception */ public static String decryptData_ECB(String key, String cipherText) throws Exception { Security.addProvider(new BouncyCastleProvider()); Cipher cipher = Cipher.getInstance(ALGORITHM_NAME_ECB_PADDING, "BC"); SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), ALGORITHM_NAME); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec); byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(cipherText)); return new String(decrypted, "UTF-8"); } } ``` 使用示例: ```java public class Test { public static void main(String[] args) throws Exception { String key = "1234567890abcdef"; String data = "hello world"; String encryptedData = SM4Util.encryptData_ECB(key, data); System.out.println("加密后的数据:" + encryptedData); String decryptedData = SM4Util.decryptData_ECB(key, encryptedData); System.out.println("解密后的数据:" + decryptedData); } } ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值