目前,我正在研究一些套接字的東西來建立一個簡單的加密聊天。服務器用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