doutandusegang2961
doutandusegang2961
2017-04-10 18:36
采纳率: 0%
浏览 75
已采纳

为什么我的服务器(Go)无法解密客户端(Java)消息?

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!

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • duan1226
    duan1226 2017-04-11 14:01
    已采纳

    SOLVED: I thought about the benefits a self-written security algorithm has for this project and came to the conclusion that default TLS would be enough for this. TLS is pretty easy to use with Go & Java so I will build up this chat application with TLS.

    Here is a nice example how to implement TLS server side in Go: Simple Golang HTTPS/TLS Examples

    Here is some information of how my client could make use of TLS and web sockets: How to use a SSL WebSocket client

    点赞 评论
  • douzhi2017
    douzhi2017 2017-04-11 09:14

    You are decrypting the base64 encoded string 's', instead of 'b64Bytes'. Your code is not compiling though, so maybe this is not the actual code? Here is a compiling solution:

    func DecryptStringRSA(s string, key rsa.PrivateKey) string {
        b64Bytes, _ := base64.StdEncoding.DecodeString(s)
        sDecrypted, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, &key, b64Bytes, nil)
        if err != nil {
            log.Println("Decryption error: ", err)
            return ""
        } else {
            return string(sDecrypted[:])
        }
    }
    
    点赞 评论

相关推荐