2017-04-10 151 views
1

目前,我正在研究一些套接字的东西来建立一个简单的加密聊天。服务器用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。

非常感谢大家的帮助!

+0

PS:我已经搜查谷歌的解决方案,没有什么工作。再次小信息:服务器代码用Go(Golang)编写,客户端代码用Java编写。 – Max

+0

当你说密钥是作为UTF8编码字符串发送的时候,你的意思是你正在编码UTF8的原始DER格式公钥并发送它? –

+0

@LukePark不,我实际上想说我正在向客户端发送Base64解码字符串。我会在我的帖子中解决这个问题。 – Max

回答

0

解决: 我想到了一个自己编写的安全算法已为这个项目带来的好处,并得出结论认为默认TLS就足够了这一点。 TLS非常容易与Go & Java一起使用,因此我将使用TLS构建此聊天应用程序。

这里是一个很好的例子如何实现TLS服务器端围棋: Simple Golang HTTPS/TLS Examples

这里是我的客户如何能利用TLS和网络插口的一些信息:How to use a SSL WebSocket client

1

您正在解密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[:]) 
    } 
} 
+0

我会稍后再试。谢谢。 – Max

+0

好吧,它仍然不起作用......我让两个程序都打印出加密的消息,以确保服务器准确接收客户端发送的内容,这看起来很好。我会在上面的问题中列举一个例子。 – Max

相关问题