sha1withrsa

https://blog.csdn.net/vr7jj/article/details/53588089

对上面播客中

openssl rsa in userkey.pem -pubout -out userpub.key

这一句其实有点小问题,执行会不成功,然后执行 openssl rsa -help发现如下

 -help              Display this summary
 -inform format     Input format, one of DER NET PEM
 -outform format    Output format, one of DER NET PEM PVK
 -in val            Input file
 -out outfile       Output file
 -pubin             Expect a public key in input file
 -pubout            Output a public key
 -passout val       Output file pass phrase source
 -passin val        Input file pass phrase source
 -RSAPublicKey_in   Input is an RSAPublicKey
 -RSAPublicKey_out  Output is an RSAPublicKey
 -noout             Don't print key out
 -text              Print the key in text
 -modulus           Print the RSA key modulus
 -check             Verify key consistency
 -*                 Any supported cipher
 -pvk-strong        Enable 'Strong' PVK encoding level (default)
 -pvk-weak          Enable 'Weak' PVK encoding level
 -pvk-none          Don't enforce PVK encoding
 -engine val        Use engine, possibly a hardware device
很容易发现in掉了-

 

还有主函数中在验签的地方memset(szTmp1, 0, sizeof(szTmp1));错误,签名的数据被清空了,那验签肯定不成功。下面将修改后的原播客贴一下:

秘钥对是我是使用openssl命令生产的给出的参考如下。另外秘钥文件格式有很多种,请注意。 
生产私钥

openssl genrsa -out userkey.pem 1024   
1
从私钥中导出公钥

openssl rsa -in userkey.pem -pubout -out userpub.key//此处修改-in
1
签名测试代码

#include <string.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>

RSA* getPrivateKey(char* in_szKeyPath)
{
    FILE    *fp = NULL; 
    char    szKeyPath[1024];
    RSA     *priRsa = NULL, *pubRsa = NULL, *pOut = NULL;

    memset(szKeyPath, 0 ,sizeof(szKeyPath));

    if(256 < strlen(in_szKeyPath))
        strncpy(szKeyPath, in_szKeyPath, 256);
    else
        strncpy(szKeyPath, in_szKeyPath, strlen(in_szKeyPath));

    printf("密钥文件路径[%s]", szKeyPath);

    /*  打开密钥文件 */
    if(NULL == (fp = fopen(szKeyPath, "rb")))
    {
        printf( "打开密钥文件[%s]出错", szKeyPath);
        return NULL;
    }
    /*  获取私密钥 */
    if(NULL == (priRsa = PEM_read_RSAPrivateKey(fp, &priRsa, NULL,NULL)))
    {
        printf( "读出私钥内容出错\n");
        fclose(fp);
        return NULL;
    }
    fclose(fp);

    printf("提取私钥\n");
    pOut = priRsa;
    return pOut;
}

RSA* getPublicKey(char* in_szKeyPath)
{
    FILE    *fp = NULL; 
    char    szKeyPath[1024];
    RSA     *priRsa = NULL, *pubRsa = NULL, *pOut = NULL;

    memset(szKeyPath, 0 ,sizeof(szKeyPath));

    if(256 < strlen(in_szKeyPath))
        strncpy(szKeyPath, in_szKeyPath, 256);
    else
        strncpy(szKeyPath, in_szKeyPath, strlen(in_szKeyPath));

    printf("密钥文件路径[%s]", szKeyPath);

    /*  打开密钥文件 */
    if(NULL == (fp = fopen(szKeyPath, "rb")))
    {
        printf( "打开密钥文件[%s]出错", szKeyPath);
        return NULL;
    }
    /*  获取公密钥 */
    if(NULL == (priRsa = PEM_read_RSA_PUBKEY(fp, &priRsa, NULL,NULL)))
    {
        printf("读出私钥内容出错\n");
        fclose(fp);
        return NULL;
    }
    fclose(fp);
    printf("提取公钥\n");
    pOut = priRsa;
    return pOut;
}

int main(void)
{
    int     flen,rsa_len, ienLen, iRet;
    RSA     *prsa = NULL;
    char    szEnData[]="orderId=01010500201502000004reqTime=20150205012727ext=20151120ext2=1";
    char    szTmp[10240], szTmp1[10240];

    if(NULL == (prsa = getPrivateKey("userkey.pem")))
    {
        RSA_free(prsa);
        printf("获取私钥失败\n");
        return -1;
    }

//  RSA_print_fp(stdout, prsa, 11);
    flen = strlen(szEnData);
        printf("待签名数据:[%s]\n", szEnData);

    memset(szTmp, 0, sizeof(szTmp));
    memset(szTmp1, 0, sizeof(szTmp1));
    //  对待签名数据做SHA1摘要
    SHA1(szEnData, flen, szTmp);
    //使用私钥对SHA1摘要做签名
    ienLen = RSA_sign(NID_sha1, (unsigned char *)szTmp, 20, (unsigned char*)szTmp1, &iRet, prsa);
    if(ienLen != 1 )
    {
            printf("签名失败\n");
            RSA_free(prsa);
            return -1;
        }
        RSA_free(prsa);
        printf("签名成功\n");
    //签名串szTmp1二进制数据需要转成base64编码
    //mac=base64encode(szTmp1)这是伪码,生产MAC值,给对方去校验

    //验证签名
    //验证签名的是需要获取MAC值,明文签名数据,对“明文签名数据”做SHA1,获得摘要。在对MAC做basedecode(mac),然后调用函数验证签名
    if(NULL == (prsa = getPublicKey("userpub.key")))
    {
        RSA_free(prsa);
        printf("获取私钥失败\n");
        return -1;
    }
    flen = strlen(szEnData);
    printf("待签名数据:[%s]\n", szEnData);//签名数据 和 mac 因该是由通信报文中获得,这里演示直接用使用同一变量

    memset(szTmp, 0, sizeof(szTmp));
    //memset(szTmp1, 0, sizeof(szTmp1));//此处修改
    //  对待签名数据做SHA1摘要
    SHA1(szEnData, flen, szTmp);

    ienLen = RSA_verify(NID_sha1, (unsigned char *)szTmp, 20, (unsigned char*)szTmp1, iRet, prsa);
    if(ienLen != 1 )
    {
            printf("签名不合法\n");
            RSA_free(prsa);
            return -1;
    }
    else
            printf("验签成功\n");
    RSA_free(prsa);
    return 0;
}
--------------------- 
作者:vr7jj 
来源:CSDN 
原文:https://blog.csdn.net/vr7jj/article/details/53588089 
版权声明:本文为博主原创文章,转载请附上博文链接!

然后其他正常,总而言之,原博主也还是很不错的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值