AES密钥编码byte []到String并返回byte []

时间:2010-05-26 17:13:57

标签: java encryption

在类似的问题"Conversion of byte[] into a String and then back to a byte[]"被认为不执行字节[]到字符串和反向转换,看起来适用于大多数情况,主要是当你不知道使用的编码时。

但是,在我的情况下,我正在尝试将数据库中的javax.crypto.SecretKey数据保存到数据库中,然后将其恢复。

接口提供了一个方法getEncoded(),它返回编码为byte []的密钥数据,而另一个类我可以使用这个byte []来恢复密钥。

所以,问题是,如何将关键字节写为String,然后返回byte []以重新生成密钥?

4 个答案:

答案 0 :(得分:6)

javax.crypto.SecretKey是二进制数据,因此您无法将其直接转换为String。您可以将其编码为十六进制字符串或Base64。

请参阅Apache Commons Codec

更新:如果您不想依赖第三方库(并且不能/不想存储纯二进制数据,正如Jon建议的那样),您可以做一些特别的编码,例如,遵循埃里克森的建议:

public static String bytesToString(byte[] b) {
    byte[] b2 = new byte[b.length + 1];
    b2[0] = 1;
    System.arraycopy(b, 0, b2, 1, b.length);
    return new BigInteger(b2).toString(36);
}

public static byte[] stringToBytes(String s) {
    byte[] b2 = new BigInteger(s, 36).toByteArray();
    return Arrays.copyOfRange(b2, 1, b2.length);
}

相当,丑陋,非标准且不是最佳(输出尺寸)。但它也非常小,正确且没有依赖性;它可以是实用的,特别是如果你的数据很小的话。

更新:我按照GregS的评论将Character.MAX_RADIX替换为文字值(36)。它可能看起来不那么优雅,但它实际上更安全。 (您也可以使用32或16)。

答案 1 :(得分:3)

使用base-64编码将任意二进制数据安全地转换为字符串并返回。

Apache Commons Codec库为此提供代码,其他各种代码也是如此。 (诚​​然,我对Apache Commons Codec的API并不十分热衷。我不知道任何其他具有此功能的库 off hand 但我确信它们存在。)

编辑:This project提供了一个用于快速编码和解码的文件,并且具有合理的方法签名 - 以及您需要的大量额外选项。

或者,如果要将其保存到数据库,为什么不使用适当的二进制数据字段(Image / Blob或适用于您的数据库的任何内容)而不是首先将其存储为字符串?

答案 2 :(得分:1)

如何编码为数字而不是字符串?它不像Base-64那么紧凑,但你可以省略Apache Commons。

/* Store the key. */
BigInteger n = new BigInteger(1, key.getEncoded()); /* Store as NUMBER, or … */
String s = n.toString(32);                          /* … store as VARCHAR. */

/* Reconstruct the key (may need to pad most significant bytes with zero). */
BigInteger n = new BigInteger(s); /* Load from VARCHAR, or … */
byte[] raw = n.toByte();          /* … load from NUMBER. */
byte[] original = new byte[16];
System.arraycopy(raw, 0, original, 16 - raw.length, raw.length);

答案 3 :(得分:0)

你不能使用String构造函数:String(byte [] data,String charsetName),如:

byte[] data=new byte[1024];
String key=new String(data,"UTF-8");

以后你可以这样做:

String key="mymostsecretaeskey";
byte[] data=key.getBytes("UTF-8");