Verifying RSA Signature iOS

前端 未结 1 1841
感动是毒
感动是毒 2021-02-08 09:00

In my static Library I have a licence file. Which I want to make sure has been generated by myself (and has not been altered). So the idea was to use an RSA Signature from what

1条回答
  •  野趣味
    野趣味 (楼主)
    2021-02-08 10:02

    The problem is lying on the way you create the signature file; following the same step I was able to produce the binary equivalent signature.sig file.

    By looking inside the hash file we can see openssl add some prefix (and hex encode the hash):

    $ cat hash
    SHA256(licence.txt)= 652b23d424dd7106b66f14c49bac5013c74724c055bc2711521a1ddf23441724
    

    So signature.sig is based on that and not on license.txt

    By using your sample and creating the signing file with:

    openssl dgst -sha256 -sign certificates/private_key.pem licence.txt > signature.sig
    

    The hashing & signing step gets correct, and the sample outputs: Alright All good!


    The final state of my file, just in case

    - (SecKeyRef)publicKeyFromFile:(NSString *) path
    {
        NSData * certificateData = [[NSFileManager defaultManager] contentsAtPath:path];
        SecCertificateRef certificateFromFile = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certificateData);
        SecPolicyRef secPolicy = SecPolicyCreateBasicX509();
        SecTrustRef trust;
        SecTrustCreateWithCertificates( certificateFromFile, secPolicy, &trust);
        SecTrustResultType resultType;
        SecTrustEvaluate(trust, &resultType);
        SecKeyRef publicKey = SecTrustCopyPublicKey(trust);
        return publicKey;
    }
    
    BOOL PKCSVerifyBytesSHA256withRSA(NSData* plainData, NSData* signature, SecKeyRef publicKey)
    {
        uint8_t digest[CC_SHA256_DIGEST_LENGTH];
        if (!CC_SHA256([plainData bytes], (CC_LONG)[plainData length], digest))
            return NO;
    
        OSStatus status = SecKeyRawVerify(publicKey,
                                          kSecPaddingPKCS1SHA256,
                                          digest,
                                          CC_SHA256_DIGEST_LENGTH,
                                          [signature bytes],
                                          [signature length]);
    
        return status == errSecSuccess;
    }
    

    PS: the malloc was a leak


    Edit:

    To make your current signature.sig file work as-is, you have to produce the same step as openssl (add prefix, hex-hash, and a newline \n), then pass this data to SecKeyRawVerify with kSecPaddingPKCS1 and not kSecPaddingPKCS1SHA256:

    BOOL PKCSVerifyBytesSHA256withRSA(NSData* plainData, NSData* signature, SecKeyRef publicKey)
    {
        uint8_t digest[CC_SHA256_DIGEST_LENGTH];
        if (!CC_SHA256([plainData bytes], (CC_LONG)[plainData length], digest))
            return NO;
    
        NSMutableString *hashFile = [NSMutableString stringWithFormat:@"SHA256(licence.txt)= "];
        for (NSUInteger index = 0; index < sizeof(digest); ++index)
            [hashFile appendFormat:@"%02x", digest[index]];
    
        [hashFile appendString:@"\n"];
        NSData *hashFileData = [hashFile dataUsingEncoding:NSNonLossyASCIIStringEncoding];
    
        OSStatus status = SecKeyRawVerify(publicKey,
                                          kSecPaddingPKCS1,
                                          [hashFileData bytes],
                                          [hashFileData length],
                                          [signature bytes],
                                          [signature length]);
    
        return status == errSecSuccess;
    }
    

    0 讨论(0)
提交回复
热议问题