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
相关产品推荐
相关产品推荐

