目前,我正在研究一些套接字的东西来建立一个简单的加密聊天。服务器用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[:])
}
}
我在客户端使用Bouncy Castle。服务器将公钥作为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
再次,这是我检查,什么是好的:
- 键转换为字符串&提交给客户
- 重点从字符串转换到AsymmetricKeyParameter
- 编码
- 加密/解密工作在一个网站上(客户端< - >客户端&服务器< - >服务器
总之什么不工作:
- 来自客户端的解密字符串
也许我没有看到一个很小的错误,或者完全忘记了一些事情。我认为他们是一些聪明的人,可以告诉我什么是错,或给我一个提示。如果您需要更多代码示例或其他信息,请随时提问。
编辑:我检查了加密的字符串,以确保服务器收到客户端发送的相同字符串。这里都是加密的字符串:
客户:
GnUapW7dxa3zXwVzNAVOJs6lcfeb6Nv0OKDM8QvPMb9jqozsGYdlET09D2Nc9F7bMfVbBMeLujlxwu8NqbvYABpoYd7uwRZJfEh/VexIEbsdkVxQUr+PEvBlE/ekkSJIV9ymCVllmRForvq7WU3pva9e56owp1NdVJGFVYVKbp8=
服务器:
GnUapW7dxa3zXwVzNAVOJs6lcfeb6Nv0OKDM8QvPMb9jqozsGYdlET09D2Nc9F7bMfVbBMeLujlxwu8NqbvYABpoYd7uwRZJfEh/VexIEbsdkVxQUr+PEvBlE/ekkSJIV9ymCVllmRForvq7WU3pva9e56owp1NdVJGFVYVKbp8=
在我看来,他们看起来一样的,所以这不应该成为问题。此外,客户端和服务器都使用OAEP和SHA256。
非常感谢大家的帮助!
PS:我已经搜查谷歌的解决方案,没有什么工作。再次小信息:服务器代码用Go(Golang)编写,客户端代码用Java编写。 – Max
当你说密钥是作为UTF8编码字符串发送的时候,你的意思是你正在编码UTF8的原始DER格式公钥并发送它? –
@LukePark不,我实际上想说我正在向客户端发送Base64解码字符串。我会在我的帖子中解决这个问题。 – Max