2011-12-27 111 views
0

我正在开发一个使用RSA和RC4的小型身份验证方案。在我目前的情况下,我试图发送一个随机生成的会话密钥给客户端,使用客户端的公钥加密。从那里,客户端将读取会话密钥,并使用其私钥对其进行解密,然后将哈希发送回服务器(我不会进入更好的安全机制,因为它们不是问题的一部分)。私钥解密对称密钥,但在对称密钥联网时给出不同结果?

目前,我已确认服务器具有客户端公钥的相同副本。我知道服务器正在使用客户端的公钥对随机生成的会话密钥进行加密。所以这里很可能没有问题。

我认为问题在于密钥的转移。关键是字符串类型,并且作为这样初始化 -

String sessionKey = new BigInteger(128, server.random).toString(128); 

并使用DataOutputStream类被传输到客户端 -

o.writeUTF(this.encryptedSessionKey); 

encryptedSessionKey是一个正常的字符串,没有特定的编码。我在想,也许,解密时,Java modified UTF-8编码,会恶化会话密钥。我解密作为这样 -

this.sessionKey = new String(cryptUtil.rsaDecrypt(clientPrivateKey, this.encryptedSessionKey.getBytes())); 
// Where encryptedSessionKey is read from the stream using i.readUTF(); 

将使用String.getBytes()上用Java编码的字符串UTF-8修改(从DataInputStream.readUTF读())来自没有特定的编码实例化的字符串返回不同的数据?

回答

2

我的猜测是,你正在做这样的事情:

byte[] encryptedSessionKeyAsBytes = cipher.doFinal(...); 
String encryptedSessionKey = new String(encryptedSessionKeyAsBytes); 

这是不对的。 String构造函数使用默认平台编码将字节转换为字符。并且所有的字节序列都不能转换为字符。例如,如果您的默认编码是ASCII,则所有负字节都不能转换为字符。

如果您必须传输二进制数据,然后将其传输为字节(使用byte []类型),或使用Base64将字节转换为可打印的字符,并使用ASCII,ISO-8859-1或UTF - 无论编码如何传输Base-64字符串。