首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > 移动开发 >

[转]CryptoAPI与OpenSSL数字签名与证验交互

2012-10-20 
[转]CryptoAPI与OpenSSL数字签名与验证交互http://www.linuxidc.com/Linux/2012-08/68721.htm这里(http://

[转]CryptoAPI与OpenSSL数字签名与验证交互
http://www.linuxidc.com/Linux/2012-08/68721.htm

这里(http://www.linuxidc.com/Linux/2012-08/68722.htm)写过了RSA非对称加密解密的交互方式,

其实数字签名也是RSA非对称加密,只不过用私钥加密的,再加上个hash摘要

CryptoAPI与openssl RSA非对称加密解密(PKCS1 PADDING)交互已经提到关于证书和私钥的数据以及对象获取,这里就不再重复讨论

1.openssl的签名及验证void opensslSigner::sign(EVP_PKEY* evpKey,BYTE** signValue,unsigned int &signLen,BYTE* text,int textLen)  {      EVP_MD_CTX mdctx;   //摘要算法上下文变量                if(evpKey == NULL)        {            printf("EVP_PKEY_new err\n");            return;        }              //以下是计算签名的代码         EVP_MD_CTX_init(&mdctx);        //初始化摘要上下文         if(!EVP_SignInit_ex(&mdctx,EVP_md5(),NULL)) //签名初始化,设置摘要算法         {            printf("err\n");            EVP_PKEY_free(evpKey);            return;        }        if(!EVP_SignUpdate(&mdctx,text,textLen)) //计算签名(摘要)Update         {            printf("err\n");            EVP_PKEY_free(evpKey);            return;        }        if(!EVP_SignFinal(&mdctx,*signValue,&signLen,evpKey))  //签名输出         {            printf("err\n");            EVP_PKEY_free(evpKey);            return;        }        printf("消息"%s"的签名值是:\n",text);        printByte(*signValue,signLen);      printf("\n");        EVP_MD_CTX_cleanup(&mdctx);      }    void opensslSigner::verify(EVP_PKEY* evpKey,BYTE* text,unsigned int textLen,BYTE* signValue,unsigned int signLen)  {      ERR_load_EVP_strings();      EVP_MD_CTX mdctx;   //摘要算法上下文变量         EVP_MD_CTX_init(&mdctx);    //初始化摘要上下文         if(!EVP_VerifyInit_ex(&mdctx, EVP_md5(), NULL)) //验证初始化,设置摘要算法,一定要和签名一致         {            printf("EVP_VerifyInit_ex err\n");            EVP_PKEY_free(evpKey);            return;        }        if(!EVP_VerifyUpdate(&mdctx, text, textLen)) //验证签名(摘要)Update         {            printf("err\n");            EVP_PKEY_free(evpKey);            return;        }        if(!EVP_VerifyFinal(&mdctx,signValue,signLen,evpKey))        {            printf("verify err\n");            EVP_PKEY_free(evpKey);            EVP_MD_CTX_cleanup(&mdctx);            return;      }        else        {            printf("验证签名正确.\n");        }        //释放内存         EVP_PKEY_free(evpKey);        EVP_MD_CTX_cleanup(&mdctx);    }  2.CryptoAPI的签名验证依然是私钥的问题,没时间再去尝试导入私钥,暂且只写验证因为也是RSA加密,所以同样要注意字节排列方式,具体看RSA加密的交互部分void verify(HCRYPTPROV hProv,PCCERT_CONTEXT cert,BYTE* text,unsigned long len,BYTE* signValue,unsigned long signLen)  {          //反序与openssl一致       for(int i = 0 ; i < signLen / 2;i++)      {          BYTE temp = signValue[i];          signValue[i] = signValue[signLen - i - 1];          signValue[signLen - i - 1] = temp;      }        // 创建离散对象           HCRYPTHASH hHash = NULL;          if(!CryptCreateHash(              hProv,                        // 容器句柄                CALG_MD5,                    // 算法标识               NULL,                        // 算法使用的Key               0,                            // 算法标识               &hHash))                    // 返回的HASH对象           {              printf("CryptCreateHash error:0X%x.\n",GetLastError());          return;      }                // 计算数据摘要           if(CryptHashData(hHash, text, len, 0) == 0)          {              printf("CryptHashData error:0X%x.\n",GetLastError());          return;      }              if(cert == NULL)          {              printf("pCertContext == NULL:0X%x.\n",GetLastError());          return;      }          //获取公钥句柄         HCRYPTKEY hPubKey;          if(!CryptImportPublicKeyInfo(hProv, cert->dwCertEncodingType, &cert->pCertInfo->SubjectPublicKeyInfo, &hPubKey))          {              printf("CryptImportPublicKeyInfo error:0X%x.\n",GetLastError());          return;      }          //验证签名         if(!CryptVerifySignature(hHash, signValue, signLen, hPubKey, NULL, 0))          {              printf("CryptVerifySignature error:0X%x.\n",GetLastError());          return;      }          cout << "sign verify successfully" << endl;  }  

热点排行