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



目前,我正在研究一些套接字的东西来构建一个简单的加密聊天。服务器是用 Go 编写的,客户端是用 Java 编写的。 我的服务器和客户端已经在工作,可以通信。我的下一个目标是加密客户端和服务器之间的流量。

我想使用 RSA 和 AES 来加密将在两个目标之间传输的所有数据。当客户端连接时,服务器会将其公共 RSA 密钥发送给客户端,客户端将加密其 AES 密钥并将其发送回服务器。

现在的主要问题是,我无法解密客户端发送回服务器的内容。我已经比较了加密数据,并尝试了我的加密/解密方法是否普遍有效。他们做到了。但是,一旦到了客户端使用公钥加密并且服务器必须使用其私钥对其进行解密的地步,它就不起作用。

下面是生成新 RSA 密钥对的服务器代码:

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}
}

这是表示 RSAKeyPair 的结构

type RSAKeyPair struct {
Private rsa.PrivateKey
Public  rsa.PublicKey
}

这是解密字符串的服务器端函数:

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[:])
}
}

我在客户端使用充气城堡。服务器将公钥作为 Base64 解码字符串发送(现在是人类可读的),客户端将字符串转换为 AsymmetricKeyParameter。这种转换也可以正常工作,我检查过了。

客户端加密字符串的方法:

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);
}

在客户端加密字符串并将其发送回服务器后,服务器应该解密它并继续执行他应该做的事情,但相反,它只会给我以下错误:

crypto/rsa: decryption error

同样,这是我检查的内容,还可以:

  • 密钥转换为字符串并提交到客户端
  • 从字符串到非对称键参数的键转换
  • 编码
  • 加密/解密在一个站点上工作(客户端<->客户端和服务器<->服务器

简而言之,什么不起作用:

  • 解密来自客户端的字符串

也许我没有看到一个很小的错误,或者只是完全忘记了什么。我认为有一些聪明的人可以告诉我哪里出了问题或给我一个提示。如果您需要更多代码示例或其他信息,请随时询问。

编辑:我检查了加密的字符串,以确保服务收到客户端发送的相同字符串。以下是两个加密字符串:

客户:

GnUapW7dxa3zXwVzNAVOJs6lcfeb6Nv0OKDM8QvPMb9jqozsGYdlET09D2Nc9F7bMfVbBMeLujlxwu8NqbvYABpoYd7uwRZJfEh/VexIEbsdkVxQUr+PEvBlE/ekkSJIV9ymCVllmRForvq7WU3pva9e56owp1NdVJGFVYVKbp8=

服务器:

GnUapW7dxa3zXwVzNAVOJs6lcfeb6Nv0OKDM8QvPMb9jqozsGYdlET09D2Nc9F7bMfVbBMeLujlxwu8NqbvYABpoYd7uwRZJfEh/VexIEbsdkVxQUr+PEvBlE/ekkSJIV9ymCVllmRForvq7WU3pva9e56owp1NdVJGFVYVKbp8=

在我看来,它们看起来是一样的,所以这不应该是问题。此外,客户端和服务器都使用带有 SHA256 的 OAEP。

提前感谢大家的帮助!

您正在解密 base64 编码的字符串 's',而不是 'b64Bytes'。不过,您的代码没有编译,所以也许这不是实际的代码?这是一个编译解决方案:

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[:])
}
}

已解决: 我想到了自写的安全算法对这个项目的好处,得出的结论是默认TLS就足够了。TLS很容易与Go和Java一起使用,所以我将使用TLS构建这个聊天应用程序。

这里有一个很好的例子,如何在Go中实现TLS服务器端: 简单的 Golang HTTPS/TLS 示例

以下是我的客户端如何使用TLS和Web套接字的一些信息:如何使用SSL WebSocket客户端

相关内容

最新更新