在类似的问题中,"Conversion of byte[] into a String and then back to a byte[]"被认为不做byte[]到字符串和反向转换,看起来像什么适用于大多数情况,主要是当你不知道使用的编码时。
但是,在我的例子中,我试图将javax.crypto.SecretKey数据保存到数据库中,然后恢复它。
该接口提供了一个方法getEncoded(),它返回编码为byte[]的密钥数据,对于另一个类,我可以使用这个byte[]来恢复密钥。
因此,问题是,我如何将密钥字节写为字符串,然后获取byte[]以重新生成密钥?
发布于 2010-05-27 01:22:53
javax.crypto.SecretKey是二进制数据,所以您不能将其直接转换为字符串。您可以将其编码为十六进制字符串或Base64。
参见Apache Commons Codec。
更新:如果你不想依赖第三方库(并且不能/不想存储纯二进制数据,就像Jon建议的那样),你可以进行一些即席编码,例如,遵循erickson的建议:
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的评论之后,我用文字值(36)替换了Character.MAX_RADIX。它可能看起来不那么优雅,但实际上更安全。(您也可以使用32或16)。
发布于 2010-05-27 01:22:16
使用base-64编码可以安全地将任意二进制数据转换为字符串,然后再转换回来。
Apache Commons Codec库提供了这方面的代码,其他各种库也是如此。(诚然,我对Apache Commons Codec的API并不是特别感兴趣。我不知道有没有其他库有这个功能,但我确信它们是存在的。)
编辑:This project提供了用于快速编码和解码的单个文件,并且有合理的方法签名-以及大量的额外选项,如果您需要它们。
或者,如果要将其保存到数据库中,为什么不使用适当的二进制数据字段(Image/Blob或任何适用于数据库的字段),而不是首先将其存储为字符串?
发布于 2010-05-27 01:46:09
如果编码成数字而不是字符串呢?它没有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);https://stackoverflow.com/questions/2915224
复制相似问题