Currently, I am working on some socket stuff to build a simple chat with encryption. The server is written in Go and the client is written in Java. My server & client are already working and can communicate. My next goal is to encrypt the traffic between client & server.
I want to use RSA and AES to encrypt all data that will be transferred between both targets. When a client connects, the server will send his public RSA key to the client which will encrypt his AES key and send it back to the server.
The main problem is now, that I can't decrypt what the client sends back to the server. I already compared the encrypted data and tried if my encryption/decryption methods work in general. And they do. But as soon as it comes to the point where the client encrypts with a public key and the server has to decrypt it with its private key it won't work.
Here is the server code that generates a new RSA key pair:
func GenerateKeyPair() RSAKeyPair {
log.Println("Generating RSA keys. This could take a while.")
startTime := time.Now()
privateKey, err := rsa.GenerateKey(rand.Reader, 1024)
if err != nil {
log.Fatal("Couldn't generate RSA keys. Message: ", err)
os.Exit(1)
}
var publicKey *rsa.PublicKey
publicKey = &privateKey.PublicKey
elapsedTime := time.Since(startTime)
log.Printf("RSA keys ready afert %s.", elapsedTime)
return RSAKeyPair{Private: *privateKey, Public: *publicKey}
}
This is the struct that represents the RSAKeyPair
type RSAKeyPair struct {
Private rsa.PrivateKey
Public rsa.PublicKey
}
This is the server-side function to decrypt a string:
func DecryptStringRSA(s string, key rsa.PrivateKey) string {
b64Bytes, _ := base64.StdEncoding.DecodeString(s)
sDecrypted, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, &key, []byte(s), nil)
if err != nil {
log.Println("Decryption error: ", err)
return ""
} else {
return string(sDecrypted[:])
}
}
I am using Bouncy Castle on the client side. The server sends the public key as Base64 decoded string (it's human readable now) and the client converts the string into an AsymmetricKeyParameter. This conversion also works fine, I checked that.
The client's method to encrypt a string:
public String encryptString(String string, AsymmetricKeyParameter publicKey) throws UnsupportedEncodingException, InvalidCipherTextException {
Security.addProvider(new BouncyCastleProvider());
RSAEngine rsaEngine = new RSAEngine();
AsymmetricBlockCipher blockCipher = new OAEPEncoding(rsaEngine, new SHA256Digest(), new SHA256Digest(), null);
blockCipher.init(true, publicKey);
byte[] bytes = string.getBytes("UTF-8");
byte[] encryptedBytes = blockCipher.processBlock(bytes, 0, bytes.length);
return Base64.getEncoder().encodeToString(encryptedBytes);
}
After the client encrypted a string and sent it back to the server, the server should decrypt it and continue doing what he is supposed to do but instead, it just gives me following error:
crypto/rsa: decryption error
Again this is what I checked and what is ok:
- Key conversion to string & submitting to client
- Key conversion from string to AsymmetricKeyParameter
- Encodings
- Encryption/Decryption works on one site (Client <-> Client & Server <-> Server
In short what is not working:
- Decrypt string which came from client
Maybe I didn't see a really small mistake or just completely forgot about something. I think there are some smart people that out there that can tell me what is wrong or give me a hint. If you need more code examples or additional information feel free to ask.
Edit: I checked the the encrypted string to make sure the serve receives the same string the client is sending. Here are both encrypted strings:
Client:
GnUapW7dxa3zXwVzNAVOJs6lcfeb6Nv0OKDM8QvPMb9jqozsGYdlET09D2Nc9F7bMfVbBMeLujlxwu8NqbvYABpoYd7uwRZJfEh/VexIEbsdkVxQUr+PEvBlE/ekkSJIV9ymCVllmRForvq7WU3pva9e56owp1NdVJGFVYVKbp8=
Server:
GnUapW7dxa3zXwVzNAVOJs6lcfeb6Nv0OKDM8QvPMb9jqozsGYdlET09D2Nc9F7bMfVbBMeLujlxwu8NqbvYABpoYd7uwRZJfEh/VexIEbsdkVxQUr+PEvBlE/ekkSJIV9ymCVllmRForvq7WU3pva9e56owp1NdVJGFVYVKbp8=
In my opinion they look the same so this shouldn't be the problem. Also client and server are both using OAEP with SHA256.
Thank you all in advance for your help!