JAVA-AES密钥长度不匹配

JAVA-AES密钥长度不匹配,java,encryption,client-server,aes,rsa,Java,Encryption,Client Server,Aes,Rsa,我有两种方法在客户端和服务器之间加密/解密JSON消息。服务器有一对RSA密钥(一个私有密钥和一个公共密钥),客户端也有。此外,由于通道本身不安全,两人都可以访问在首次建立通信时生成的对称会话密钥,该密钥用于对JSON消息进行加密。客户端生成AES密钥(会话密钥),然后使用服务器的公钥(众所周知)对其进行加密,并将其发送给服务器,服务器解密会话密钥并将其存储在客户端ID下的哈希映射中 但问题是:我在发送之前检查了密钥长度,它有16字节长。当服务器接收到加密的会话密钥并对其进行解密时,它的长度为2

我有两种方法在客户端和服务器之间加密/解密JSON消息。服务器有一对RSA密钥(一个私有密钥和一个公共密钥),客户端也有。此外,由于通道本身不安全,两人都可以访问在首次建立通信时生成的对称会话密钥,该密钥用于对JSON消息进行加密。客户端生成AES密钥(会话密钥),然后使用服务器的公钥(众所周知)对其进行加密,并将其发送给服务器,服务器解密会话密钥并将其存储在客户端ID下的
哈希映射中

但问题是:我在发送之前检查了密钥长度,它有16字节长。当服务器接收到加密的会话密钥并对其进行解密时,它的长度为24字节。我想在这两者之间一定出了什么问题,无论是在加密还是解密过程中。这是一个问题,因为当客户端想要开始发送请求(以加密JSON消息的形式)时,服务器无法破译和读取请求,因为密钥的大小不正确(它抛出一个
java.security.InvalidKeyException
:非法密钥大小或默认参数)

密码/解密方法发布如下:

公共字符串密码(密钥、字符串alg、字符串msg){
试一试{
Cipher c=Cipher.getInstance(alg);
c、 init(Cipher.ENCRYPT_模式,密钥);
返回encoder.encodeToString(c.doFinal(msg.getBytes(“UTF-8”));
}捕获(非法块大小异常e){
(...)
}
}
编码器
/
解码器
来自
java.util.Base64

公共字符串解密(密钥、字符串alg、字符串msg){
试一试{
Cipher c=Cipher.getInstance(alg);
c、 init(密码解密模式,密钥);
返回新字符串(c.doFinal(decoder.decode(msg)),“UTF-8”);
}捕获(非法块大小异常e){
(...)
}
}
客户端加密和发送会话密钥:

SecretKey sk=KeyGenerator.getInstance(“AES/CBC/PKCS5Padding”).generateKey();
System.out.println(sk.getEncoded().length)//长度=16字节
字符串sessionKey=cipher(client.getServerPublicKey(),
“RSA/ECB/PKCS5Padding”,encoder.encodeToString(sk.getEncoded());
write(“{(…),\“key\:\”+sessionKey+“\”}”);
服务器接收加密会话密钥并将其保存在
HashMap

byte[]aux=decipher(registry.getServerPrivateKey(),
“RSA/ECB/PKCS5Padding”,data.get(“key”).toString().replace(“\”,”)
.getBytes(“UTF-8”);
System.out.println(aux.length)//长度=24字节
registry.addSession(…,新的SecretKeySpec(aux,0,aux.length,“AES”);

我尝试了不同的算法和不同的填充,但我似乎不知道错误在哪里。

在使用以下语句加密之前,您正在对密钥进行base64编码:

String sessionKey = cipher(client.getServerPublicKey(),
    "RSA/ECB/PKCS5Padding", encoder.encodeToString(sk.getEncoded()));
…将16字节的密钥转换为24字符长的base64表示形式。加密之前不需要对密钥进行base64编码,因为加密完全能够处理二进制数据。请尝试以下方法:

String sessionKey = cipher(client.getServerPublicKey(),
    "RSA/ECB/PKCS5Padding", sk.getEncoded());
同时更改您的
密码(…)
方法,将消息接受为
字节[]

public String cipher(Key key, String alg, byte[] msg){
    try {
        Cipher c = Cipher.getInstance(alg);
        c.init(Cipher.ENCRYPT_MODE, key);
        return encoder.encodeToString(c.doFinal(msg));
    } catch (IllegalBlockSizeException e) {
        (...)
    }
}
另外,将
解密(…)
更改为二进制,如:

public byte[] decipher(Key key, String alg, String msg){
    try {
        Cipher c = Cipher.getInstance(alg);
        c.init(Cipher.DECRYPT_MODE,key);
        return c.doFinal(decoder.decode(msg));
    } catch (IllegalBlockSizeException e) {
        (...)
    }
}

这当然解决了密钥大小问题,现在客户端和服务器端的密钥大小都是16字节,谢谢!这
encoder.encodeToString(sk.getEncoded())
是我以前尝试过的实现的剩余部分。