Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/grails/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何将“AES”密钥从byth[]转换为UTF-8字符串_Java_Android_Encryption_Public Key Encryption - Fatal编程技术网

Java 如何将“AES”密钥从byth[]转换为UTF-8字符串

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

我需要将secretKey.getEncoded从字节[]转换为字符串,以便将密钥保存到db并通过消息将密钥发送给另一方

现在我想用Base64 24字节来读,但另一方只能读UTF-8格式的16字节

我尝试这样做:stringstr=newstringbytes,Charsets.UTF_8; 但是我得到了错误的乱七八糟的格式,有这样的等式标记:k��$��v/~M�6.�L�

正确的方法是什么

 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();
    }
}