且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

发送RSA公钥到iphone并使用它加密

更新时间:2023-01-18 09:37:25

这应该做你想要的 - 它使用服务器的公钥加密数据。它不受MITM攻击,除非攻击者拥有您的私钥和密码的副本(通过非SSL通信,但是,仍然是,但使用服务器的合法公钥加密的数据几乎不可能解密) 。

This should do what you're asking - it encrypts data with the server's public key. It's not subject to MITM attacks, unless the attacker has a copy of your private key and its password (communicating via non-SSL, however, still is, but the data you encrypt with the server's legit public key will be nearly impossible to decrypt).

我从苹果的文档,这个网站,苹果开发者论坛和可能在其他地方拼凑了这一切。所以感谢大家我cribbed代码!此代码假设了几个事情:

I cobbled this together from Apple's docs, this site, the Apple developer forums and probably elsewhere. So thanks to everyone I cribbed code from! This code assumes several things:


  1. 您已经生成了RSA密钥对(我使用4096位密钥它看起来很快),并使用私钥创建了一个DER编码证书,称为cert.cer,你放在你的应用程序的资源包(显然,你也可以从你的服务器下载证书,但然后你再次打开MITM攻击)。默认情况下,OpenSSL会生成PEM编码的证书,因此您必须使用openssl x509 -in cert.pem -inform PEM -out cert.cer -outform DER进行转换。 iOS将在PEM上barf。我使用证书的原因是它实际上更容易使用,并在iOS中受支持。

  1. You've already generated your RSA key pairs (I'm using a 4096-bit key and it seems speedy enough) and, using the private key, created a DER-encoded certificate called "cert.cer" that you put in your resource bundle of your app (obviously, you can also download the cert from your server, but then you're open to MITM attacks again). By default, OpenSSL generates a PEM encoded cert, so you have to convert it with "openssl x509 -in cert.pem -inform PEM -out cert.cer -outform DER". iOS will barf on PEM. The reason I use a cert is it's actually easier to work with, and is supported in iOS. Using just the public key isn't (though it can be done).

您已将Security.framework添加到您的项目中,然后#import< Security / Security.h>。

You've added Security.framework to your project and you #import <Security/Security.h>.

/ *
返回加密文本的NSData如果加密不成功。

将X.509证书作为NSData(例如,从dataWithContentsOfFile:)
* /

/* Returns an NSData of the encrypted text, or nil if encryption was unsuccessful.
Takes the X.509 certificate as NSData (from dataWithContentsOfFile:, for example) */

+(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];
}