麻烦encryption在iOS上和使用RAW RSA在Node.js解密

我正在尝试在iOS端encryption一些东西,并在我的node.js服务器上解密它。 在服务器上,我正在使用库伪造。 我能够encryption一些东西,并在node.js上进行解密,而且工作。 我这样encryption: const encryptedPassword = publicKey.encrypt(password, 'RAW'); 并像这样解密: const password = privateKey.decrypt(encryptedPassword, 'RAW');

现在,我不想在服务器上进行encryption,而是想在我的iOS应用上进行encryption,但仍然使用相同的方式进行解密。 我发现这个库,swift-rsautils。 https://github.com/btnguyen2k/swift-rsautils/blob/master/Swift-RSAUtils/RSAUtils.swift它有这个函数称为encryptWithRSAKey ,这就是我正在使用的。 由于是原始encryption,我试图通过填充SecPaddingNone。 但是,不幸的是,它不起作用,我无法解密在服务器上。 错误信息是无效的长度,并且base64数据的长度似乎要大得多。 有谁知道我可以如何解决这个问题?

这是我的iOS代码:

 let dataString = text.dataUsingEncoding(NSUTF8StringEncoding) let certificateLabel = "certificate" let certificateRef = self.getCertificateFromKeyChain(certificateLabel) let certificateData = self.getDataFromCertificate(certificateRef) let cryptoImportExportManager = CryptoExportImportManager() let publicKeyRef = cryptoImportExportManager.importPublicKeyReferenceFromDERCertificate(certificateData) let encryptedData = self.encryptWithRSAKey(data, rsaKeyRef: publicKeyRef!, padding: SecPadding.None) let base64EncryptedString = encryptedData?.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0)) 

然后,我发送这个base64encryptionstring到服务器,并尝试使用私钥解密。 它不幸的工作。

这不是你的确切问题的答案,因为我没有使用特定的库,但我已经玩了一些JavaScript和node.js的encryption。

我能够实现eccjs库,这是使用非对称椭圆曲线支持构build的Stanford Javascript Crypto Library(SJCL)。

在node.js端:

 var ecc = require('eccjs'); var cryptoKeys = ecc.generate(ecc.ENC_DEC); //crypto_keys.enc is the pubic key for encoding. crypto_keys.dec is the private key for decoding. //send the public key to the client app.get('/PublicKey', function(req, res){ res.setHeader('Cache-Control', 'private, no-cache, no-store, must-revalidate'); res.setHeader('Expires', '-1'); res.setHeader('Pragma', 'no-cache'); res.setHeader('Content-type', 'text/plain'); res.send('var publicKey = ' + JSON.stringify(cryptoKeys.enc) + ';'); }); //authenticate a user name and a password (encrypted by client) against the domain controller app.get('/Authenticate', function(req, res){ res.setHeader('Content-type', 'text/plain'); var url = "ldap://na-us-dc01.am.corp.airliquide.com"; var userPrincipalName = req.query.username + "@US-AIRLIQUIDE"; try { var cipherMessage = JSON.parse(req.query.encryptedPassword); var password = ecc.decrypt(cryptoKeys.dec, cipherMessage); //... Authentication goes here ... } catch(err) { console.log("Error with authentication: ",err); res.send("Error with authentication: " + JSON.stringify(err,null,' ')); } }); 

在客户端:

 <script src="ecc.js"></script> <script src="../PublicKey"></script> <!-- This returns the variable publicKey which has been set equal to the server's public key --> <script> function login() { var plainTextPassword = document.getElementById('password').value; var cipherTextPassword = ecc.encrypt(publicKey, plainTextPassword); var username = document.getElementById('name').value; console.log(ecc, publicKey, cipherTextPassword); var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = (function() { if (xhttp.readyState == 4 && xhttp.status == 200) { document.getElementById('result').innerHTML = xhttp.responseText; console.log("Response: " + xhttp.responseText); } }).bind(this); xhttp.open("GET", "../Authenticate?username=" + username + "&encryptedPassword=" + JSON.stringify(cipherTextPassword), true); xhttp.send(); } </script> 

我相信这个解决scheme不是非常安全的,我最终没有使用它,而是实现了HTTPS。 但是,如果这是您的最终目标,这应该为您提供必要的部分来执行您自己的非对称encryption。

SecPadding.None已经从Swift3中删除,Swift-RSAUtils的代码已经改变,所以我不能重现你的问题。 但是我能够用下面的代码encryption然后解密数据:

 let data = "Data to be encrypted".data(using: String.Encoding.utf8)! let e = RSAUtils.encryptWithRSAKey(data, rsaKeyRef: publicSecKeyRef, padding: SecPadding()) let d = try! RSAUtils.decryptWithRSAPrivateKey(encryptedData: e!, privkeyBase64: privkey) 

你可以用https://github.com/btnguyen2k/swiftutils最新版本的Swift-RSAUtils重试吗&#xFF1F;

编辑:我注意到你有错误“无效的消息长度”。 值得注意的是,RSA不能一次encryption大量的数据。 它可以encryption一个消息,直到key's size - 11长度。 为了解决这个限制,Swift-RSAUtils将长数据分成小块,encryption每个块并将它们合并在一起。 所以,在服务器端,你应该这样做:将encryption的数据分成key's size块,解密每一个并合并到最终的结果。