当前位置: 首页 > 知识库问答 >
问题:

在iOS上加密和在节点上解密时遇到问题。使用原始RSA的js

佴阳辉
2023-03-14

我试图在iOS端加密一些东西,然后在我的节点上解密。js服务器。在服务器上,我正在使用library forge。我能够在node上对某些内容进行加密和解密。js,这很有效。我这样加密:const encryptedPassword=publicKey。加密(密码“RAW”) 并按如下方式解密:const password=privateKey。解密(encryptedPassword,“RAW”)

现在,我不想在服务器上加密,我想在我的iOS应用上加密,但仍然用同样的方式解密。我找到了这个图书馆,swift rsautils。https://github.com/btnguyen2k/swift-rsautils/blob/master/Swift-RSAUtils/RSAUtils.swift它有一个名为encryptWithRSAKey的函数,我正在使用这个函数。由于它是原始加密,我尝试传入padding 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))

然后我将这个base64加密字符串发送到服务器,并尝试使用私钥解密。不幸的是,它不起作用。


共有2个答案

怀德馨
2023-03-14

SecPadd。Swift3中没有删除任何内容,并且Swift-RSAUtils的代码已更改,因此我无法重现您的问题。但是我可以使用以下代码加密然后解密数据:

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再试一次吗?

编辑:我注意到您出现错误“无效消息长度”。请注意,RSA无法一次性加密大量数据。它可以加密密钥大小为11的消息。为了解决这一限制,Swift RSAUtils将长数据分割成小块,加密每个块并将它们合并在一起。因此,在服务器端,您应该做类似的事情:将加密的数据分割成密钥大小的块,对每个块进行解密并将其合并到最终结果。

明利
2023-03-14

这并不是你确切问题的答案,因为我没有使用那个特定的库,但我在javascript和node中玩了一些加密。js。

我能够实现eccjs库,它是使用非对称椭圆曲线支持构建的斯坦福Javascript加密库(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>

我确信这个解决方案并不完全安全,我最终没有使用它,而是实现了HTTPS。然而,如果这是您的最终目标,这应该为您提供必要的部分来执行您自己的非对称加密。

 类似资料:
  • 问题内容: 我有一个从Java服务器发送的公钥。在我解码并去除ASN.1标头之前,base64编码的字符串匹配。我使用将公钥存储在钥匙串中。 因此,我尝试使用公共密钥对数据进行加密,并使用Java中的私有密钥对其进行解密。我在iOS端和Java端使用。 我正在加密的是对称AES密钥,该密钥对我的实际数据进行加密,因此密钥长度为16个字节。当简单地对密钥进行base64编码时,一切正常,因此我知道此

  • 我一直在试图找出java安全/加密库的方法,我相信我在理解发生了什么方面取得了一些进展。我想我设法让加密部分工作了。在encrypt方法中,如果我只是尝试返回,我会得到一些看起来像加密文本的不可读的杂乱无章的东西。当我试图不返回它,而是继续调用decrypt并进行明文-->encrypt-->decrypt是我所拥有的一切时,问题就来了 所以我用一些明文调用encrypt,并尝试返回明文以确保它工

  • 我有一条在java上使用以下代码加密的kafka消息: 现在我正在尝试在我已经知道私钥的解码消息上使用python对其进行解码。我尝试使用(因为我使用的是python3和仅适用于2. x)像在他们的文档中一样使用此代码,但它不起作用: 我得到了这个错误代码:我试图寻找一种方法使私钥成为JWK对象,但找不到。 我知道我的消息是JWE,因为它被4个点分割,当我对第一部分进行base64解码时,我得到了

  • 我使用的是Web加密,更具体地说,这些示例是:https://github.com/diafygi/webcrypto-examples/#rsa-oaep 更新

  • 我正在尝试解密AES加密数据(在. NET中加密),但我的解密结果字符串似乎不可读,并且我没有收到任何错误。 数据加密使用: < li>Padding: PKCS7Padding < li>KeySize: 128 < li >模式:CBC, 我有InItVector、PassCode、salt和NumberOfPassword(3)次迭代。 这是我的代码: 下面是在 .NET 端加密数据的代码: