非对称 public / 私钥加密 RSA with nodeJS and Objective-C
Asymmetric public / private key encryption RSA with nodeJS and Objective-C
我想使用非对称加密 (RSA) 加密我的服务器(用 nodeJS 编写)和 iOS 应用程序(用 objective-C 编写)之间的通信。
我要做的是只加密我从 iOS 应用 (使用 public 密钥) 发送到服务器,服务器需要解密数据(使用私钥)才能读取。
出于测试目的,使用 GitHub 中的以下库,我能够使用 objective-C 成功加密然后解密字符串 "hello world!"。 注意:NSString* encWithPubKey为加密后的base64字符串
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!
使用以下 link,出于测试目的,我还能够使用 nodeJs 加密然后解密字符串 "hello world!":
https://coolaj86.com/articles/asymmetric-public--private-key-encryption-in-node-js
var fs = require('fs');
var ursa = require('/PATH/ursa');
var pubkeyAlice = ursa.createPublicKey(fs.readFileSync("/PATH/public.pem"));
var privkeyAlice = ursa.createPrivateKey(fs.readFileSync("/PATH/private.pem"));
var msg = "hello world!";
var enc = pubkeyAlice.encrypt(msg, 'utf8', 'base64');
console.log('encrypted string:'+enc);
var rcv = privkeyAlice.decrypt(enc, 'base64', 'utf8');
console.log('decrypted', rcv, '\n');
以下两个示例都成功打印了 "hello world!"。接下来,我从 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');
但是,当这样做时,我在 nodeJS 中收到以下错误:
- 错误:error:040A1079:rsaroutines:RSA_padding_check_PKCS1_OAEP_mgf1:oaep解码错误
根据我的理解,这个错误意味着加密的字符串无效。但是,我无法理解为什么会出现此错误。如果我使用相同的语言,我可以加密和解密相同的字符串,但是,我无法在两种语言之间进行通信。
请注意 iOS 应用程序和 nodeJS 分别使用以下 public 和私钥:
-----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-----
我尝试上网查找,但找不到足够的资源来解决问题。任何帮助将不胜感激!谢谢!
不要。 加密两个系统之间通信的正确解决方案是使用 TLS。尝试自己实施加密几乎肯定不会有好结果,并且最终会导致您的密码被破解 - 非常 很难安全地实施加密,以至于即使是经验丰富的密码学家也会避免它无论他们在哪里。
在 IRC 上与作者进一步讨论了这个问题,并确定反对使用 TLS 的理由是 "the client can load a custom CA and intercept the requests with something like Burp anyway":
不可能防止客户端修改。客户端根本上不受信任,技术上不可能确保客户端确实如此不篡改请求。相反,请求的验证应该发生在服务器端,这样 无关紧要 客户端进行什么样的篡改。 This article 更详细。
感谢 Curious Programmer 我从这个 link:
中找到了答案
我现在需要 node-rsa 而不仅仅是 rsa。我修复我的代码的行是这样的:
myDecrypter.setOptions({encryptionScheme: 'pkcs1'});
其中 myDecrypter 是私钥。
我想使用非对称加密 (RSA) 加密我的服务器(用 nodeJS 编写)和 iOS 应用程序(用 objective-C 编写)之间的通信。
我要做的是只加密我从 iOS 应用 (使用 public 密钥) 发送到服务器,服务器需要解密数据(使用私钥)才能读取。
出于测试目的,使用 GitHub 中的以下库,我能够使用 objective-C 成功加密然后解密字符串 "hello world!"。 注意:NSString* encWithPubKey为加密后的base64字符串
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!
使用以下 link,出于测试目的,我还能够使用 nodeJs 加密然后解密字符串 "hello world!":
https://coolaj86.com/articles/asymmetric-public--private-key-encryption-in-node-js
var fs = require('fs'); var ursa = require('/PATH/ursa'); var pubkeyAlice = ursa.createPublicKey(fs.readFileSync("/PATH/public.pem")); var privkeyAlice = ursa.createPrivateKey(fs.readFileSync("/PATH/private.pem")); var msg = "hello world!"; var enc = pubkeyAlice.encrypt(msg, 'utf8', 'base64'); console.log('encrypted string:'+enc); var rcv = privkeyAlice.decrypt(enc, 'base64', 'utf8'); console.log('decrypted', rcv, '\n');
以下两个示例都成功打印了 "hello world!"。接下来,我从 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');
但是,当这样做时,我在 nodeJS 中收到以下错误:
- 错误:error:040A1079:rsaroutines:RSA_padding_check_PKCS1_OAEP_mgf1:oaep解码错误
根据我的理解,这个错误意味着加密的字符串无效。但是,我无法理解为什么会出现此错误。如果我使用相同的语言,我可以加密和解密相同的字符串,但是,我无法在两种语言之间进行通信。
请注意 iOS 应用程序和 nodeJS 分别使用以下 public 和私钥:
-----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-----
我尝试上网查找,但找不到足够的资源来解决问题。任何帮助将不胜感激!谢谢!
不要。 加密两个系统之间通信的正确解决方案是使用 TLS。尝试自己实施加密几乎肯定不会有好结果,并且最终会导致您的密码被破解 - 非常 很难安全地实施加密,以至于即使是经验丰富的密码学家也会避免它无论他们在哪里。
在 IRC 上与作者进一步讨论了这个问题,并确定反对使用 TLS 的理由是 "the client can load a custom CA and intercept the requests with something like Burp anyway":
不可能防止客户端修改。客户端根本上不受信任,技术上不可能确保客户端确实如此不篡改请求。相反,请求的验证应该发生在服务器端,这样 无关紧要 客户端进行什么样的篡改。 This article 更详细。
感谢 Curious Programmer 我从这个 link:
中找到了答案我现在需要 node-rsa 而不仅仅是 rsa。我修复我的代码的行是这样的:
myDecrypter.setOptions({encryptionScheme: 'pkcs1'});
其中 myDecrypter 是私钥。