iOS开发笔记--使用iOS验证OpenSSL产生的ECDSA签名

版权声明:本文为博主原创文章,未经博主同意不得转载。 https://blog.csdn.net/iDivines/article/details/81943210
    int        ret;
    int        nid;
    ECDSA_SIG *sig;
    EC_KEY    *eckey;
    unsigned char digest [20];
    size_t dataToSignLen = 20;
    uint8_t hash[CC_SHA256_DIGEST_LENGTH];
    CC_SHA256(digest, (uint32_t)dataToSignLen, hash);
//    NID_X9_62_c2tnb191v1
    nid = OBJ_sn2nid("prime256v1");
    
    eckey = EC_KEY_new_by_curve_name(nid);
    if (eckey == NULL)
    {
        /* error */
        perror("EC_KEY_new_by_curve_name");
    }
    
    if (!EC_KEY_generate_key(eckey))
    {
        /* error */
    }
    else
    {// 打印一下ec的私钥和公钥
        EC_KEY_print_fp(stdout, eckey, 0);
    }
    // Second step: compute the ECDSA signature of a SHA-1 hash value using ECDSA_do_sign
    
    
    sig = ECDSA_do_sign(hash, CC_SHA256_DIGEST_LENGTH, eckey);// 签名
    if (sig == NULL)
    {
        /* error */
        perror("ECDSA_do_sign");
    }
    else
    {// 打印一下签名,r和s
        printf("Signature:\n\tr=%s\n\ts=%s\n", BN_bn2hex(sig->r), BN_bn2hex(sig->s));
    }
    
    // Third step: verify the created ECDSA signature using ECDSA_do_verify
    ret = ECDSA_do_verify(hash, CC_SHA256_DIGEST_LENGTH, sig, eckey);// 验证
    
    if (ret == -1)
    {
        /* error */
        perror("ECDSA_do_verify");
    }
    else if (ret == 0)
    {
        /* incorrect signature */
        printf("Verified Failure\n");
    }
    else   /* ret == 1 */
    {
        /* signature ok */
        printf("Verified OK\n");
        
    }
    
    //1.获取签名结果
    unsigned char signChar[100] = {0};
    unsigned char *p = signChar;
    int len = i2d_ECDSA_SIG(sig, &p);
    NSData *signature = [NSData dataWithBytes:signChar length:len];
    NSLog(@"%@",signature);
    
    //2.获取公钥
    const EC_POINT *pubkey = EC_KEY_get0_public_key(eckey);
    const EC_GROUP *ec_group = EC_KEY_get0_group(eckey);
    BIGNUM *x = BN_new();
    BIGNUM *y = BN_new();
    
    if (EC_POINT_get_affine_coordinates_GFp(ec_group, pubkey, x, y, NULL)) {
        printf("公钥:\n");
        BN_print_fp(stdout, x);
        putc('\n', stdout);
        BN_print_fp(stdout, y);
        putc('\n', stdout);
    }
    
    unsigned char char_x[32] = {0};
    unsigned char char_y[32] = {0};
    BN_bn2bin(x,char_x);
    BN_bn2bin(y,char_y);
    
    unsigned char pubkeyChar[65] = {0};
    pubkeyChar[0] = 0x04;
    for(int i=0; i<32; i++){
        pubkeyChar[i+1] = char_x[i];
        pubkeyChar[i+1+32] = char_y[i];
    }
    NSData *pubKeyData = [NSData dataWithBytes:pubkeyChar length:65];
    NSLog(@"%@",pubKeyData);
    
    //3.产生IOS使用的公钥对象
    NSDictionary *dic = @{
                          (__bridge id)kSecAttrKeyType : (__bridge id)kSecAttrKeyTypeEC,
                          (__bridge id)kSecAttrKeyClass : (__bridge id)kSecAttrKeyClassPublic,
                          (__bridge id)kSecAttrKeySizeInBits : @(256)
                          };
    
    NSError *error = nil;
    SecKeyRef pubSecKey = SecKeyCreateWithData((CFDataRef)pubKeyData, (CFDictionaryRef)dic, (void *)&error);
    if(error){
        NSLog(@"产生IOS使用的公钥对象失败");
    }else{
        NSLog(@"产生IOS使用的公钥对象成功");
    }
    
    //4.验证签名
    SecKeyAlgorithm algorithm = kSecKeyAlgorithmECDSASignatureMessageX962SHA256;
    BOOL canEncrypt = SecKeyIsAlgorithmSupported(pubSecKey, kSecKeyOperationTypeVerify, algorithm);
    if(!canEncrypt){
        return;
    }
    
    NSData *signedData = [NSData dataWithBytes:digest length:20];
    SecKeyVerifySignature(pubSecKey, kSecKeyAlgorithmECDSASignatureMessageX962SHA256, (CFDataRef)signedData, (CFDataRef)signature, (void *)&error);
    if(error){
        NSLog(@"IOS验证签名失败");
    }else{
        NSLog(@"IOS验证签名成功");
    }

猜你喜欢

转载自blog.csdn.net/iDivines/article/details/81943210