通过IV传输AES 256加密

时间:2014-06-29 13:02:07

标签: java c# encryption aes

我厌倦了将编码逻辑转换为用C#编写的java。我传递一个自定义IV作为参数。

 private static byte[] iv = new byte[] { 116,209,63,154,85,66,37,82,96,104,131,192,103,140,125,176 };

但是,在一个字节数组中,java不能容纳多于128个。在C#中它是可能的。

        this.secretKeySpec = new SecretKeySpec(key, "AES");
        this.iv = new IvParameterSpec(iv);
        this.cipher = Cipher.getInstance(ALGORITHM_AES256);

在javax.crypto中,IvParameterSpec constactory只允许字节数组为“iv”。任何人都可以帮助在java中传递上面的byte []作为iv参数。

2 个答案:

答案 0 :(得分:2)

问题是Java不支持unsigned datatypes,而.NET则支持{。<}。

无符号字节从0到255.这是.NET Byte结构
有符号字节是-128到127.这是Java byte原始数据类型或.NET SByte结构。

.Net代码中的数据将iv存储为无符号值,而Java代码不允许您直接执行此操作。

<强>解决方案:

1)你可以手动从.NET代码中的每个字节中减去128,从而使它代表相同的位模式(IV只是位序列 - 它们是否存储为有符号或无符号值无关紧要 - 它是必须匹配的位:)

byte[] iv = new byte[] { -8, 81, ...};

2)或者您可以将相同的数据存储在int数据类型数组中,并使用以下代码将它们转换为字节值。

int[] ivInInts = new int[] { 116,209,63,154,85,66,37,82,96,104,131,192,103,140,125,176 };

byte[] iv = new byte[ivInInts.getLength()];

for (int i = 0; i < ivInInts.getLength(); i++)
   iv = (byte)(ivInInts[i] - 128);

修改

如果您对数字的二进制等价有疑问,可以阅读two's complement numbers

65 = 0100 0001为无符号字节= 0100 0001为有符号字节
-65 =不能表示为无符号字节= 1011 1111作为有符号字节
193 = 1011 1111为无符号字节=不能表示为有符号字节

答案 1 :(得分:1)

Eugene提议的替代方案:只需显式转换所有值 - 或高于127的值 - 转换为byte。将十六进制用于二进制数据也是一个好主意。

byte[] test = new byte[] { 0, (byte) 0, 0x00, (byte) 0x00, (byte) 128, (byte) 0x80, (byte) 256, (byte) 0x100 };

请注意 - 由于最后两个字节的值应该清楚 - 这允许您指定超出范围的值而不会发出警告。

或者,您可以使用十六进制或base64解码器,这样您就可以使用字符串创建更密集的字节数组表示。