我有字符串"0443"
,其长度为4.如果我使用UTF编码,它会改变长度吗?
我需要将这些字符传递给initialisationVector
,但initialisationVector
接受8个字节的长度。
有什么方法可以使用UTF编码将"0443"
改为8个字节?
public static String decrypt(byte[] b) throws Exception{
byte[] key = "12345678".getBytes("UTF-16");
byte[] iv ="0443".getBytes("UTF-16");
System.out.println("Length of iv" + iv.length + "key length.." + key.length);
SecretKey secretKey = new SecretKeySpec(key, "RC2");
System.out.println("Key size" + secretKey.getEncoded().length);
Cipher cipher = Cipher.getInstance("RC2/CBC/NoPadding");
IvParameterSpec initialisationVector = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, secretKey, initialisationVector);
byte[] cipherText = cipher.doFinal(b);
String plainText = new String(cipherText, "UTF-8");
System.out.println("Decrypted Text :: " + plainText);
return "";
}
答案 0 :(得分:2)
你的数组中有10个字节而不是8个,因为Java在文本之前输出byte order mark(Little Endian vs Big Endian)。如果你只想要普通的8字节,你需要找出接收字节的代码所期望的格式,然后指定它。
byte[] iv ="0443".getBytes("UTF-16BE");
或
byte[] iv ="0443".getBytes("UTF-16LE");
这将只给出具有指定表示的字符的8个字节。
答案 1 :(得分:2)
Affe的回答似乎很好,但正如你的问题显示出一些理解问题,这里有一些一般性的话:
我有字符串
"0443"
,其长度为4.如果我使用UTF进行编码, 它会改变长度吗?
没有编码“UTF”。 UTF代表 Unicode(或UCS)转换格式,是编码的系列:
"0443"
这样的ASCII字符串将以4个字节编码,ASCII之外的每个字符都需要多个字节(最多四个字节)。对于UTF-32和UTF-16,每个单元内的字节顺序很重要,因此有两个常见版本(Big Endian和Little Endian)。如果消息的接收者可能不知道字节顺序(或者可能是编码),则有时字节顺序标记将被添加到编码文本中。 (对于UTF-8,字节的顺序是固定的。)
如果使用UTF-16
进行编码,Java会执行此操作,因此您将获得两个以上的字节。请改用UTF-16BE
或UTF16LE
,不添加此字节。
关于您的加密:
将"12345678"
之类的简单字符串直接用作加密密钥通常是个坏主意。这种方式(假设只有十进制数字)只有log_2(10 ^ 8)~26.6位的熵,而不是128位密钥可能的128位。尝试使用此表单的所有可能键将在几秒钟内完成。
初始化向量的使用取决于mode of operation。您正在使用CBC模式,其中初始化向量应该是随机的(在确定明文之前甚至不能部分预测)。固定的初始化向量使您的加密更加虚弱。
使用随机密钥,或者,如果必须使用密码,请使用较长的密码并使用一些盐(以及高迭代次数)对其进行哈希处理,例如使用PBKDF2或bcrypt ,生成密钥。 (盐可以随消息一起发送,也可以通过参数(例如通信伙伴的名称)生成,只是每次使用时都不同。)
如果要生成密钥,还可以从相同的数据生成IV(但请确保为每条消息使用不同的盐)。否则,生成随机初始化向量并将其与每条消息一起发送。 (它不需要保密,只需随机。)
此外,您应该将加密与message authentication code结合使用,否则您将对CBC模式下的选择密文攻击持开放态度。