Java 如何将“AES”密钥从byth[]转换为UTF-8字符串
我需要将secretKey.getEncoded从字节[]转换为字符串,以便将密钥保存到db并通过消息将密钥发送给另一方 现在我想用Base64 24字节来读,但另一方只能读UTF-8格式的16字节 我尝试这样做:stringstr=newstringbytes,Charsets.UTF_8; 但是我得到了错误的乱七八糟的格式,有这样的等式标记:k��$��v/~M�6.�L� 正确的方法是什么Java 如何将“AES”密钥从byth[]转换为UTF-8字符串,java,android,encryption,public-key-encryption,Java,Android,Encryption,Public Key Encryption,我需要将secretKey.getEncoded从字节[]转换为字符串,以便将密钥保存到db并通过消息将密钥发送给另一方 现在我想用Base64 24字节来读,但另一方只能读UTF-8格式的16字节 我尝试这样做:stringstr=newstringbytes,Charsets.UTF_8; 但是我得到了错误的乱七八糟的格式,有这样的等式标记:k��$��v/~M�6.�L� 正确的方法是什么 public static String generateAESKey() throws Exce
public static String generateAESKey() throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
SecretKey secretKey = kgen.generateKey();
return new String(Base64.encode(secretKey.getEncoded(), Base64.NO_WRAP));
}
以字节数组的形式生成密钥,可用于加密和解密进程
private SecretKey secretKey; // member variables (in class)
public byte[] generateAESKey() {
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
if (secretKey == null) {
secretKey = kgen.generateKey();
}
byte[] keyBytes = secretKey.getEncoded();
//Log.i("keyBytes", toHexString(keyBytes));
return keyBytes;
}
catch (Exception ex){
ex.printStackTrace();
}
return null;
}
GenerateAsKey的结果:
0x04 0x90 0x74 0x21 0x73 0xB9 0x3D 0x1F 0x7B 0x19 0xC4 0x95 0x85 0x20 0xDF 0x27
以字符串形式生成密钥,您可以将其保存或发送到其他应用程序
public String getStrAESkey() {
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
if (secretKey == null) {
secretKey = kgen.generateKey();
}
String keyStr = toHexString(secretKey.getEncoded());
Log.i("keyStr", keyStr);
return keyStr;
}
catch (Exception ex){
ex.printStackTrace();
}
return null;
}
getStrAESkey的结果:
0490742173B93D1F7B19C4958520DF27
//
Utils.java
public class Utils {
private static final char[] hexCode = "0123456789ABCDEF".toCharArray();
private static int hexToBin(char ch) {
if ('0' <= ch && ch <= '9') return ch - '0';
if ('A' <= ch && ch <= 'F') return ch - 'A' + 10;
if ('a' <= ch && ch <= 'f') return ch - 'a' + 10;
return -1;
}
public static byte[] parseHexBinary(String s) {
final int len = s.length();
if (len % 2 != 0)
throw new IllegalArgumentException("hexBinary needs to be even-length: " + s);
byte[] out = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
int h = hexToBin(s.charAt(i));
int l = hexToBin(s.charAt(i + 1));
if (h == -1 || l == -1)
throw new IllegalArgumentException("contains illegal character for hexBinary: " + s);
out[i / 2] = (byte) (h * 16 + l);
}
return out;
}
public static String printHexBinary(byte[] data) {
StringBuilder r = new StringBuilder(data.length * 2);
for (byte b : data) {
r.append(hexCode[(b >> 4) & 0xF]);
r.append(hexCode[(b & 0xF)]);
}
return r.toString();
}
}
你能试试String str=newstringsecretkey.toString,Charsets.UTF_8;您是如何初始化变量字节的?@Arik6 AES密钥是随机或伪随机的,例如来自KDF字节字符串。在您的情况下,16字节对应于128位密钥。考虑到它是随机的或接近随机的,为什么您希望尝试将这些随机字节解释为UTF-8字符串不会只产生随机垃圾?我建议您和/或另一方推迟进行加密,直到您更好地理解一些基本概念。如果加密做得不好,可能会对用户信任和隐私造成危险。@Arik6 UTF-8的某些值是不可打印的,如前几个值是控制字节。因此,不可能将具有0-255之间所有可能值的字节数组转换为可读字符串。这就是为什么要用base64好吧我不明白。在问题的文本中,您声称不知道如何将二进制字节数组转换为字符串,并给出一个示例,说明为什么这样做行不通。然后你展示了正确的代码,你问什么是正确的方法。谢谢你的回答,但是在我写的时候,当我这样做的时候,我得到了一个不正确的乱码字符串格式,例如:k��$��v/~M�6.�L�这完全是不正确的,可能会导致信息丢失、安全性降低和无法解密。此外,这几乎是一个复制粘贴的方法,OP已经说,他使用,并认为是错误的。我的答案基于参考文献这里,
public class Utils {
private static final char[] hexCode = "0123456789ABCDEF".toCharArray();
private static int hexToBin(char ch) {
if ('0' <= ch && ch <= '9') return ch - '0';
if ('A' <= ch && ch <= 'F') return ch - 'A' + 10;
if ('a' <= ch && ch <= 'f') return ch - 'a' + 10;
return -1;
}
public static byte[] parseHexBinary(String s) {
final int len = s.length();
if (len % 2 != 0)
throw new IllegalArgumentException("hexBinary needs to be even-length: " + s);
byte[] out = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
int h = hexToBin(s.charAt(i));
int l = hexToBin(s.charAt(i + 1));
if (h == -1 || l == -1)
throw new IllegalArgumentException("contains illegal character for hexBinary: " + s);
out[i / 2] = (byte) (h * 16 + l);
}
return out;
}
public static String printHexBinary(byte[] data) {
StringBuilder r = new StringBuilder(data.length * 2);
for (byte b : data) {
r.append(hexCode[(b >> 4) & 0xF]);
r.append(hexCode[(b & 0xF)]);
}
return r.toString();
}
}