简体   繁体   English

具有nodeJS和Objective-C的非对称公钥/私钥加密RSA

[英]Asymmetric public / private key encryption RSA with nodeJS and Objective-C

I want to encrypt the communication between my server (written in nodeJS) and the iOS app (written in objective-C) using asymmetric encryption (RSA). 我想使用非对称加密(RSA)加密我的服务器(用nodeJS编写)和iOS应用程序(用Objective-C编写)之间的通信。

What I am looking to do is to only encrypt the data that I send from the iOS app (using the public key) to the server, where the server needs to decrypt the data (using the private key) in order to read it. 我要做的是只加密我从iOS应用程序(使用公钥)发送到服务器的数据,服务器需要解密数据(使用私钥)才能读取它。

Using the following library from GitHub, for testing purposes, I was able to successfully encrypt and then decrypt the string "hello world!" 使用GitHub中的以下库进行测试,我能够成功加密然后解密字符串“hello world!”。 using objective-C. 使用Objective-C。 Note: NSString* encWithPubKey is the encrypted base64 string 注意: NSString * encWithPubKey是加密的base64字符串

  • https://github.com/ideawu/Objective-C-RSA https://github.com/ideawu/Objective-C-RSA

     NSString *pubkey = @"-----BEGIN PUBLIC KEY-----\\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDI2bvVLVYrb4B0raZgFP60VXY\\ncvRmk9q56QiTmEm9HXlSPq1zyhyPQHGti5FokYJMzNcKm0bwL1q6ioJuD4EFI56D\\na+70XdRz1CjQPQE3yXrXXVvOsmq9LsdxTFWsVBTehdCmrapKZVVx6PKl7myh0cfX\\nQmyveT/eqyZK1gYjvQIDAQAB\\n-----END PUBLIC KEY-----"; NSString *privkey = @"-----BEGIN PRIVATE KEY-----\\nMIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMMjZu9UtVitvgHS\\ntpmAU/rRVdhy9GaT2rnpCJOYSb0deVI+rXPKHI9Aca2LkWiRgkzM1wqbRvAvWrqK\\ngm4PgQUjnoNr7vRd1HPUKNA9ATfJetddW86yar0ux3FMVaxUFN6F0KatqkplVXHo\\n8qXubKHRx9dCbK95P96rJkrWBiO9AgMBAAECgYBO1UKEdYg9pxMX0XSLVtiWf3Na\\n2jX6Ksk2Sfp5BhDkIcAdhcy09nXLOZGzNqsrv30QYcCOPGTQK5FPwx0mMYVBRAdo\\nOLYp7NzxW/File//169O3ZFpkZ7MF0I2oQcNGTpMCUpaY6xMmxqN22INgi8SHp3w\\nVU+2bRMLDXEc/MOmAQJBAP+Sv6JdkrY+7WGuQN5O5PjsB15lOGcr4vcfz4vAQ/uy\\nEGYZh6IO2Eu0lW6sw2x6uRg0c6hMiFEJcO89qlH/B10CQQDDdtGrzXWVG457vA27\\nkpduDpM6BQWTX6wYV9zRlcYYMFHwAQkE0BTvIYde2il6DKGyzokgI6zQyhgtRJ1x\\nL6fhAkB9NvvW4/uWeLw7CHHVuVersZBmqjb5LWJU62v3L2rfbT1lmIqAVr+YT9CK\\n2fAhPPtkpYYo5d4/vd1sCY1iAQ4tAkEAm2yPrJzjMn2G/ry57rzRzKGqUChOFrGs\\nlm7HF6CQtAs4HC+2jC0peDyg97th37rLmPLB9txnPl50ewpkZuwOAQJBAM/eJnFw\\nF5QAcL4CYDbfBKocx82VX/pFXng50T7FODiWbbL4UnxICE0UBFInNNiWJxNEb6jL\\n5xd0pcy9O2DOeso=\\n-----END PRIVATE KEY-----"; NSString *originString = @"hello world!"; // Demo: encrypt with public key NSString *encWithPubKey = [RSA encryptString:originString publicKey:pubkey]; NSLog(@"Enctypted with public key: %@", encWithPubKey);// prints the encrypted string in base64 format // Demo: decrypt with private key NSString *decWithPrivKey = [RSA decryptString:encWithPubKey privateKey:privkey]; NSLog(@"Decrypted with private key: %@", decWithPrivKey);// prints -> hello world! 

Using the following link, for testing purposes as well, I was also able to encrypt and then decrypt the string "hello world!" 使用以下链接,为了测试目的,我也能够加密然后解密字符串“hello world!”。 using nodeJs: 使用nodeJs:

Both of the following examples printed "hello world!" 以下两个例子都印有“你好世界!” successfully. 成功。 Next, I took the encrypted string, NSString*encWithPubKey , from what I got in objective-C (which is in base64 format) and then I tried to decrypt it with nodeJS: 接下来,我从Objective-C(base64格式)中获取加密字符串NSString * encWithPubKey ,然后尝试使用nodeJS解密它:

    var privkeyAlice = ursa.createPrivateKey(fs.readFileSync("/PATH/private.pem"));

    var enc = <  HERE IS THE ENCRYPTED STRING RECEIVED FROM Objective-C : encWithPubKey  >
    var rcv = privkeyAlice.decrypt(enc, 'base64', 'utf8');
    console.log('decrypted', rcv, '\n');

However, when doing so, I receive the following error in nodeJS: 但是,这样做时,我在nodeJS中收到以下错误:

  • Error: error:040A1079:rsa routines:RSA_padding_check_PKCS1_OAEP_mgf1:oaep decoding error 错误:错误:040A1079:rsa例程:RSA_padding_check_PKCS1_OAEP_mgf1:oaep解码错误

From my understanding, this error means that the encrypted string was invalid. 根据我的理解,此错误意味着加密的字符串无效。 However, I am unable to understand why I am getting this error. 但是,我无法理解为什么我收到此错误。 I am able to encrypt and decrypt the same string if I do it with the same language, however, I am unable to communicate between the two languages. 如果我使用相同的语言,我能够加密和解密相同的字符串,但是,我无法在这两种语言之间进行通信。

Please note that BOTH the iOS app and the nodeJS are using the following public and private keys respectively: 请注意,iOS应用程序和nodeJS分别使用以下公钥和私钥:

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDI2bvVLVYrb4B0raZgFP60VXY
cvRmk9q56QiTmEm9HXlSPq1zyhyPQHGti5FokYJMzNcKm0bwL1q6ioJuD4EFI56D
a+70XdRz1CjQPQE3yXrXXVvOsmq9LsdxTFWsVBTehdCmrapKZVVx6PKl7myh0cfX
QmyveT/eqyZK1gYjvQIDAQAB
-----END PUBLIC KEY-----


-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMMjZu9UtVitvgHS
tpmAU/rRVdhy9GaT2rnpCJOYSb0deVI+rXPKHI9Aca2LkWiRgkzM1wqbRvAvWrqK
gm4PgQUjnoNr7vRd1HPUKNA9ATfJetddW86yar0ux3FMVaxUFN6F0KatqkplVXHo
8qXubKHRx9dCbK95P96rJkrWBiO9AgMBAAECgYBO1UKEdYg9pxMX0XSLVtiWf3Na
2jX6Ksk2Sfp5BhDkIcAdhcy09nXLOZGzNqsrv30QYcCOPGTQK5FPwx0mMYVBRAdo
OLYp7NzxW/File//169O3ZFpkZ7MF0I2oQcNGTpMCUpaY6xMmxqN22INgi8SHp3w
VU+2bRMLDXEc/MOmAQJBAP+Sv6JdkrY+7WGuQN5O5PjsB15lOGcr4vcfz4vAQ/uy
EGYZh6IO2Eu0lW6sw2x6uRg0c6hMiFEJcO89qlH/B10CQQDDdtGrzXWVG457vA27
kpduDpM6BQWTX6wYV9zRlcYYMFHwAQkE0BTvIYde2il6DKGyzokgI6zQyhgtRJ1x
L6fhAkB9NvvW4/uWeLw7CHHVuVersZBmqjb5LWJU62v3L2rfbT1lmIqAVr+YT9CK
2fAhPPtkpYYo5d4/vd1sCY1iAQ4tAkEAm2yPrJzjMn2G/ry57rzRzKGqUChOFrGs
lm7HF6CQtAs4HC+2jC0peDyg97th37rLmPLB9txnPl50ewpkZuwOAQJBAM/eJnFw
F5QAcL4CYDbfBKocx82VX/pFXng50T7FODiWbbL4UnxICE0UBFInNNiWJxNEb6jL
5xd0pcy9O2DOeso=
-----END PRIVATE KEY-----

I've tried to look online, but I wasn't able to find enough resources to solve the problem. 我试图在网上看,但我找不到足够的资源来解决这个问题。 Any help will be appreciated! 任何帮助将不胜感激! Thank you! 谢谢!

Don't. 别。 The correct solution to encrypt communication between two systems is to use TLS. 加密两个系统之间通信的正确解决方案是使用TLS。 Trying to implement encryption yourself is almost certainly not going to end well and will end up with your crypto being broken - it's very hard to securely implement encryption, to the point that even experienced cryptographers avoid it wherever they can. 尝试自己实施加密几乎肯定不会很好地结束并最终导致你的加密被破坏 - 安全地实施加密非常困难,即使是经验丰富的密码学家也无论如何都要避免加密。

After having discussed this question on IRC a bit more with the author, and determining that the rationale against using TLS was that "the client can load a custom CA and intercept the requests with something like Burp anyway": 在IRC上与作者讨论了这个问题之后,并确定反对使用TLS的理由是“客户端可以加载自定义CA并使用像Burp这样的东西拦截请求”:

Preventing client modifications is not possible. 不可能防止客户端修改。 The client is fundamentally untrusted, and it is a technical impossibility to ensure that a client does not tamper with requests. 客户端基本上是不可信的,确保客户端不会篡改请求是技术上不可能的 Instead, the validation of requests should happen on the server-side, so that it doesn't matter what kind of tampering the client does. 相反,请求的验证应该在服务器端进行,因此无论客户端做什么样的篡改都无关紧要 This article goes into more detail. 本文将详细介绍。

Thanks to Curious Programmer I found the answer from this link: 感谢Curious Programmer,我从这个链接找到了答案:

I now require node-rsa instead of just rsa. 我现在需要node-rsa而不仅仅是rsa。 And I the line that fixed my code is this: 我修复我的代码的行是这样的:

    myDecrypter.setOptions({encryptionScheme: 'pkcs1'});

where myDecrypter is the private key. 其中myDecrypter是私钥。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM