La signature et la vérification sur iOS en utilisant RSA

Comment signer et vérifier certaines données sur iOS avec une clé RSA (de préférence en utilisant le système own libcommonCrypto)?

19
demandé sur miho 2014-02-12 13:53:50

1 réponses

depuis qu'il n'y a pas eu presque aucune connaissance sur la signature et la vérification trouvé sur StackOverflow et les docs D'Apple, j'ai dû parcourir manuellement autour dans les fichiers d'en-tête iOS et trouvé SecKeyRawSign et SecKeyRawVerify. Les lignes de code suivantes semblent fonctionner.


Signature NSData (à l'aide de SHA256 avec RSA):

NSData* PKCSSignBytesSHA256withRSA(NSData* plainData, SecKeyRef privateKey)
{
    size_t signedHashBytesSize = SecKeyGetBlockSize(privateKey);
    uint8_t* signedHashBytes = malloc(signedHashBytesSize);
    memset(signedHashBytes, 0x0, signedHashBytesSize);

    size_t hashBytesSize = CC_SHA256_DIGEST_LENGTH;
    uint8_t* hashBytes = malloc(hashBytesSize);
    if (!CC_SHA256([plainData bytes], (CC_LONG)[plainData length], hashBytes)) {
        return nil;
    }

    SecKeyRawSign(privateKey,
                  kSecPaddingPKCS1SHA256,
                  hashBytes,
                  hashBytesSize,
                  signedHashBytes,
                  &signedHashBytesSize);

    NSData* signedHash = [NSData dataWithBytes:signedHashBytes
                                        length:(NSUInteger)signedHashBytesSize];

    if (hashBytes)
        free(hashBytes);
    if (signedHashBytes)
        free(signedHashBytes);

    return signedHash;
}

vérification (en utilisant SHA256 avec RSA):

BOOL PKCSVerifyBytesSHA256withRSA(NSData* plainData, NSData* signature, SecKeyRef publicKey)
{
    size_t signedHashBytesSize = SecKeyGetBlockSize(publicKey);
    const void* signedHashBytes = [signature bytes];

    size_t hashBytesSize = CC_SHA256_DIGEST_LENGTH;
    uint8_t* hashBytes = malloc(hashBytesSize);
    if (!CC_SHA256([plainData bytes], (CC_LONG)[plainData length], hashBytes)) {
        return nil;
    }

    OSStatus status = SecKeyRawVerify(publicKey,
                                      kSecPaddingPKCS1SHA256,
                                      hashBytes,
                                      hashBytesSize,
                                      signedHashBytes,
                                      signedHashBytesSize);

    return status == errSecSuccess;
}

Alternatives (OpenSSL):

il existe une très bonne alternative disponible qui utilise OpenSSL directement au lieu de libCommonCrypto. MIHCrypto est une bibliothèque Objective-C wrapper bien conçue pour OpenSSL qui rend le travail avec la cryptographie très facile. Voir l'exemple ci-dessous.

création d'une clé est simple:

MIHAESKeyFactory *factory = [[MIHAESKeyFactory alloc] init];
id<MIHSymmetricKey> aesKey = [factory generateKey];

ou chargement d'une clé à partir fichier:

NSData *privateKeyData = [[NSFileManager defaultManager] contentsAtPath:"mykey.pem"];
MIHRSAPrivateKey *privateKey = [[MIHRSAPrivateKey alloc] initWithData:privateKeyData];

maintenant, signez quelque chose:

NSError *signingError = nil;
NSData *message = // load something to sign from somewhere
NSData *signature = [privateKey signWithSHA256:message error:&signingError]

pour plus d'exemples parcourir le MIHCrypto page.

29
répondu miho 2014-08-30 10:23:56