版权声明:本文为博主原创文章,未经博主同意不得转载。 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验证签名成功");
}