将字符串更改为unicode会改变其长度吗?

时间:2011-12-12 23:08:20

标签: java string encoding cryptography

我有字符串"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 "";
}

2 个答案:

答案 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)转换格式,是编码的系列

  • UTF-8以不同数量的8位单位(字节)对字符串进行编码。像"0443"这样的ASCII字符串将以4个字节编码,ASCII之外的每个字符都需要多个字节(最多四个字节)。
  • UTF-16以不同数量的16位单位(双字节)对字符串进行编码。最常见的字符在一个这样的单元中编码,但有一些(原则上多于单个字符,但不太常用)需要两个这样的单元。
  • UTF-32(或UCS-4)以32位为单位(四字节)对字符串进行编码。每个角色都需要4个字节。

对于UTF-32和UTF-16,每个单元内的字节顺序很重要,因此有两个常见版本(Big Endian和Little Endian)。如果消息的接收者可能不知道字节顺序(或者可能是编码),则有时字节顺序标记将被添加到编码文本中。 (对于UTF-8,字节的顺序是固定的。)

如果使用UTF-16进行编码,Java会执行此操作,因此您将获得两个以上的字节。请改用UTF-16BEUTF16LE,不添加此字节。

关于您的加密

"12345678"之类的简单字符串直接用作加密密钥通常是个坏主意。这种方式(假设只有十进制数字)只有log_2(10 ^ 8)~26.6位的熵,而不是128位密钥可能的128位。尝试使用此表单的所有可能键将在几秒钟内完成。

初始化向量的使用取决于mode of operation。您正在使用CBC模式,其中初始化向量应该是随机的(在确定明文之前甚至不能部分预测)。固定的初始化向量使您的加密更加虚弱。

使用随机密钥,或者,如果必须使用密码,请使用较长的密码并使用一些盐(以及高迭代次数)对其进行哈希处理,例如使用PBKDF2bcrypt ,生成密钥。 (盐可以随消息一起发送,也可以通过参数(例如通信伙伴的名称)生成,只是每次使用时都不同。)

如果要生成密钥,还可以从相同的数据生成IV(但请确保为每条消息使用不同的盐)。否则,生成随机初始化向量并将其与每条消息一起发送。 (它不需要保密,只需随机。)

此外,您应该将加密与message authentication code结合使用,否则您将对CBC模式下的选择密文攻击持开放态度。