You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java移除C#加密后解密结果中小端字节0的方法求助

问题解决:C# UTF-16LE加密后Java端解密乱码/多余0字节处理

问题背景

C#端加密前用Encoding.Unicode把字符串转成字节数组,加密后转Base64传给Java。Java端解密后用UTF-8解码,得到的字符串每个字符后面都带0;尝试用UTF-16解码又出现乱码。

C#加密代码:

var myBytes = Encoding.Unicode.GetBytes(myValue);
var encryptedResult = cryptoClient.Encrypt(EncryptionAlgorithm.RsaOaep, myBytes);
var encryptedmyString = Convert.ToBase64String(encryptedResult.Ciphertext);

Java初始解密代码:

byte[] code = Base64.getDecoder().decode(encryptedmyString);
DecryptResult decryptionResult = cryptoClient.decrypt(EncryptionAlgorithm.RSA_OAEP, code);
String result = new String(decryptionResult.getPlainText(), StandardCharsets.UTF_8);

原因解析

  • C#里的Encoding.Unicode对应的是UTF-16小端序(UTF-16LE),每个ASCII字符会被编码成两个字节:字符本身字节 + 0字节。用UTF-8解码时,0字节会被保留,导致字符串里每个字符后带0。
  • Java的StandardCharsets.UTF_16默认是UTF-16大端序(UTF-16BE),和C#的编码端序不匹配,直接解码就会出现乱码。

解决方法

直接用Java的StandardCharsets.UTF_16LE解码解密后的字节数组,就能正确还原原始字符串:

byte[] code = Base64.getDecoder().decode(encryptedmyString);
DecryptResult decryptionResult = cryptoClient.decrypt(EncryptionAlgorithm.RSA_OAEP, code);
// 改用UTF-16LE解码
String result = new String(decryptionResult.getPlainText(), StandardCharsets.UTF_16LE);

如果仅处理ASCII字符场景(不推荐用于含非ASCII的字符串),也可以手动过滤字节数组里的0字节后用UTF-8解码:

byte[] plainText = decryptionResult.getPlainText();
byte[] filtered = new byte[plainText.length / 2];
for (int i = 0, j = 0; i < plainText.length; i += 2) {
    filtered[j++] = plainText[i];
}
String result = new String(filtered, StandardCharsets.UTF_8);

内容的提问来源于stack exchange,提问作者Abe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 23:42:28