我目前正在处理一些加密问题,之前我正在使用原始RSA,由于缺少使用低密钥大小加密的数据(仅使用4096位密钥大小的501字节),我停止使用原始RSA。 现在我尝试使用通用的AES / RSA组合(使用RSA加密AES会话密钥,然后使用此AES密钥加密数据)
我的问题如下: 当客户端连接到服务器时,服务器首先发送带有4096位密钥的RSA公钥。之后,客户端为该会话生成会话密钥,并使用服务器的公钥对其进行加密。然后,客户端将加密的会话密钥发送到服务器,再次对其进行解密,并初始化密码。
为了解决主要冲突,我现在发送AES密钥NOT ENCRYPTED,但它也不起作用。当服务器从客户端收到某些内容时,输出如下:
Got some line from client: ÖÞà^ò}펀;ÕrJ]ám+›míé?1©ûPü.ÃæV.ë-½f?•Ž[öº[ÿÂÌwvñ{$Ä+ÞQ0IÄØþ3<ú«¸bræ‰ÚԶ¼ÔI—tîí‚øT%+ÑÓä™)
Got some line from client: O¬Aé0ü? ¿
Got some line from client: f±OßStæÂd{,¨3ýk¿ËEfo„|a>«ž6ÀN`˜ržöžuØÀ²©ïZq‹¡êœþpE¥
正如您所看到的,它显然不是它应该是什么(服务器的命令)。这里有一些代码:
LoginHandler.java(服务器)
try
{
// Transfer of the RSA 4096 key to encrypt session key
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Storage.getKeyPair().getPublic().getEncoded());
String keyBuffer = HexEncoder.byteArrayToHexString(x509EncodedKeySpec.getEncoded());
this.targetUser.getOutputStream().write(keyBuffer + "\n");
this.targetUser.getOutputStream().flush();
System.out.println("After key write");
System.out.println("pubkey buffer: " + HexEncoder.hexStringToByteArray(keyBuffer).hashCode());
System.out.println("string key: " + keyBuffer);
this.targetUser.initDecryption();
String loginDecrypted = this.targetUser.getEncryptionTool().decrypt(this.targetUser.getInputStream().readLine());
if (loginDecrypted.startsWith("LOGIN"))
{
if (this.doLoginProcedure(loginDecrypted)) // <- The main login stuff happens here
{
try
{
// Old key transfer
/**byte[] clientPubkeyBuffer = HexEncoder.hexStringToByteArray(this.targetUser.getInputStream().readLine());
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(clientPubkeyBuffer);
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);**/
// Receive the encrypted session key from client
byte[] wrappedKey = new byte[16];
this.targetUser.getRawInput().read(wrappedKey, 0, 16);
System.out.println("key wrapped: " + HexEncoder.byteArrayToHexString(wrappedKey));
// Decrypt the session key
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, Storage.getKeyPair().getPrivate());
SecretKey key = new SecretKeySpec(wrappedKey, "AES");
if (!IMServer.getServer().getCache().isKeyCached((SecretKey)key))
{
IMServer.getServer().getCache().addKey(this.targetUser.getUserID(), (SecretKey)key);
}
// Old encryption initialization
/**this.targetUser.initEncryption(publicKey);**/
// New encryption
this.targetUser.setEncryptionStreams(Encryption.decryptInputStream(this.targetUser.getRawInput(), (SecretKey)key), Encryption.encryptOutputStream(this.targetUser.getRawOutput(), (SecretKey)key));
IMServer.getServer().getClientHandlerByUser(targetUser.getUserID()).start();
}
catch (Exception ex)
{
this.targetUser.logout();
ex.printStackTrace();
}
}
else
{
targetUser.logout();
targetUser = null;
}
}
}
catch (IOException ex)
{
IMServer.getServer().getSystemLogger().log(Logger.ERROR, "Failure during login procedure");
}
方法“setEncryptionStreams()”(服务器):
public void setEncryptionStreams(InputStream is, OutputStream os)
{
this.input = new BufferedInputStream(is);
this.output = new BufferedOutputStream(os);
this.reader = new BufferedReader(new InputStreamReader(is));
this.writer = new BufferedWriter(new OutputStreamWriter(os));
System.out.println("Finished setting new streams.");
}
方法“initEncryption()”(客户端):
public void initEncryption()
{
try
{
KeyGenerator keygen = KeyGenerator.getInstance("AES");
SecureRandom random = new SecureRandom();
keygen.init(random);
SecretKey key = keygen.generateKey();
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, CBClient.pubkey);
System.out.println("PUBKEY SERVER: " + HexEncoder.byteArrayToHexString(CBClient.pubkey.getEncoded()));
System.out.println("standard length: " + key.getEncoded().length);
byte[] encryptedAesKey = key.getEncoded();
System.out.println("wrapped length: " + encryptedAesKey.length);
//this.output.write(encryptedAesKey);
this.output.write(encryptedAesKey);
this.output.flush();
System.out.println("wrapped key: " + HexEncoder.byteArrayToHexString(encryptedAesKey));
cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, key);
this.output = new BufferedOutputStream(new CipherOutputStream(this.output, cipher));
this.input = new BufferedInputStream(new CipherInputStream(this.input, cipher));
this.writer = new BufferedWriter(new OutputStreamWriter(this.output));
this.reader = new BufferedReader(new InputStreamReader(this.input));
}
catch (Exception e)
{
e.printStackTrace();
}
}
你能告诉我我做错了什么吗?我试着解决这个问题大约2天了,我真的很累。我想这很容易,但我只是看不到它。
感谢。