我有一個TCP套接字服務器,我想做到以下幾點W/O使用SSL:發送RSA公鑰到iPhone,並用它來加密
- 在服務器上,使RSA密鑰對(我知道如何使用openssl的加密庫來做到這一點)
- 在服務器上,將公鑰發送給iphone並保留私鑰。
- 在客戶端(iphone)上,要使用SecKeyEncrypt使用公鑰加密消息。
- 在服務器上,解密消息。
該消息足夠短,以便PKCS1填充結果適合128個字節。
我不知道該怎麼做2〜4。有誰知道?
我有一個TCP套接字服務器,我想做到以下幾點W/O使用SSL:發送RSA公鑰到iPhone,並用它來加密
該消息足夠短,以便PKCS1填充結果適合128個字節。
我不知道該怎麼做2〜4。有誰知道?
這應該做你所問 - 它使用服務器的公鑰加密數據。它不受MITM攻擊,除非攻擊者擁有私鑰和密碼副本(通過非SSL進行通信,但是,現在仍然存在,但用服務器的合法公鑰加密的數據幾乎不可能解密) 。
我把蘋果的文檔,本網站,Apple開發人員論壇和其他地方的軟件拼湊在一起。所以,感謝所有人,我從代碼中刪除了代碼!此代碼假定幾件事情:
您已經生成您的RSA密鑰對(我使用4096位密鑰,它似乎不夠迅速),並使用私鑰創建DER編碼證書稱爲「cert.cer」,您將其放入應用程序的資源包中(顯然,您也可以從服務器上下載證書,但隨後又再次面臨MITM攻擊)。默認情況下,OpenSSL生成一個PEM編碼證書,因此您必須將其轉換爲「openssl x509 -in cert.pem -inform PEM -out cert.cer -outform DER」。 iOS將會在PEM上發射。我使用證書的原因是它實際上更容易處理,並且在iOS中受到支持。只使用公鑰不是(儘管它可以完成)。
您已將Security.framework添加到您的項目中,並且#import <Security/Security.h>。
/* 返回加密文本的NSData,如果加密不成功,則返回nil。
注意到X.509證書作爲NSData的(從dataWithContentsOfFile :,例如) */
+(NSData *)encryptString:(NSString *)plainText withX509Certificate:(NSData *)certificate {
SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)certificate);
SecPolicyRef policy = SecPolicyCreateBasicX509();
SecTrustRef trust;
OSStatus status = SecTrustCreateWithCertificates(cert, policy, &trust);
SecTrustResultType trustResult;
if (status == noErr) {
status = SecTrustEvaluate(trust, &trustResult);
}
SecKeyRef publicKey = SecTrustCopyPublicKey(trust);
const char *plain_text = [plainText UTF8String];
size_t blockSize = SecKeyGetBlockSize(publicKey);
NSMutableData *collectedCipherData = [NSMutableData data];
BOOL success = YES;
size_t cipherBufferSize = blockSize;
uint8_t *cipherBuffer = malloc(blockSize);
int i;
for (i = 0; i < strlen(plain_text); i += blockSize-11) {
int j;
for (j = 0; j < blockSize-11 && plain_text[i+j] != '\0'; ++j) {
cipherBuffer[j] = plain_text[i+j];
}
int result;
if ((result = SecKeyEncrypt(publicKey, kSecPaddingPKCS1, cipherBuffer, j, cipherBuffer, &cipherBufferSize)) == errSecSuccess) {
[collectedCipherData appendBytes:cipherBuffer length:cipherBufferSize];
} else {
success = NO;
break;
}
}
/* Free the Security Framework Five! */
CFRelease(cert);
CFRelease(policy);
CFRelease(trust);
CFRelease(publicKey);
free(cipherBuffer);
if (!success) {
return nil;
}
return [NSData dataWithData:collectedCipherData];
}
嗯,我想你會需要發佈你的公共密鑰到外部世界(在你的情況下iPhone)。要做到最好的方法是發佈一個包含公鑰的證書,並且iPhone應用可以下載它。然後,iPhone應用程序可以利用PGP的原理用對稱算法(如AES)對數據進行加密,並用公鑰對稱加密。服務器中的應用程序將接收到消息,使用其私鑰解密對稱密鑰,然後使用由此獲得的對稱密鑰來解密加密的數據。
但是正如cobbal所說,任何人都可以攔截服務器和iPhone之間的消息,並且可以更改它,並且服務器不知道它是否實際上從iPHone接收到數據,除非您使用SSL證書(即用iPhone的私鑰加密方法的散列)。
我的建議是,使用可用的第三方應用程序,而不是自己做,因爲它們可能會在執行過程中遇到一些問題。 PGP是一個公共可用的庫,你可以使用。
不是一個問題,據我可以看到。 – 2010-11-18 03:44:19
格雷格對不起。我剛剛添加了一個問題。 – 2010-11-18 03:53:51
沒有SSL,這將不安全;它會受到[中間人攻擊](http://en.wikipedia.org/wiki/Man_in_the_middle_attack)的影響。 – cobbal 2010-11-18 04:03:08