• RSA体系 c++/java相互进行加签验签--转


    在web开发中,采用RSA公钥密钥体系自制ukey,文件证书登陆时,普遍的做法为:在浏览器端采用c++ activex控件,使用 c++的第三库openssl进行RAS加签操作,在服务器端采用java对客户端的签名进行验签操作。这就涉及到c++ openssl和java之间交互加签验签对客户端身份进行验证的过程。

           如果你通过搜索查到我这边文章,相信你一定发现,采用openssl加签后的 数据,在java端却验签不成功,使用openssl验签可以通过。问题在于openssl的公钥发在服务端转换成java RSA 公钥时有问题,openssl的公钥格式里附加了它自己的一些额外信息。所以在服务端java构造自己的pubkey时必须先剔除openssl的特有信息。

           例如如果我么采用openssl生成 modulus size 为1024, exponent为65537 的公钥秘钥对---RSA_generate_key(1024, 65537, NULL, NULL);那么我们在java端通过openssl的公钥构造java格式的公钥时,我们就必须采用如下方式获得modulus ,然后采用java的方式构造公钥,进行验签操作。

    private static byte[] getModulus(byte[] pkData, int begin){

    byte[] modData = new byte[128] ;

    byte[] ss = {pkData[0],pkData[1],pkData[2],pkData[3]};

    for(int i = 0, y = begin; i < 128; i++,y++){

    modData[i] = pkData[y];

    }

    return modData;

    }

    /**

     * 从openssl中提起相关的128为的公钥数据

     * @param b64Str

     * @return

     */

    private static byte[] get128PkData(String b64Str){

    String pk = b64Str.replace("-----BEGIN RSA PUBLIC KEY-----", "");//剔除前面的信息

    pk = pk.replace("-----END RSA PUBLIC KEY-----", "");// 剔除后面的信息

    byte[] pkData = Base64.decode(pk);

    return getModulus(pkData, 7);//下标从7开始,获得128 bytes的modulus

    }

    /** 如果你问我里边到底加了一些什么信息,我也不知道,我是从下标1开始不断测试,才得出应该从下标7开始获取modulus值 ***/

    /**

     * 由1024位的公钥转换成x509格式的公钥

     * @param modData

     * @return

     * @throws Exception

     */

    private static PublicKey getPublicKey(byte[] modData) throws Exception{

    KeyFactory keyf = KeyFactory.getInstance("RSA");

    RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(modData), new BigInteger("65537"));

    RSAPublicKey pk = (RSAPublicKey) keyf.generatePublic(pubKeySpec);

    // 解密由base64编码的公钥,并构造X509EncodedKeySpec对象

    java.security.spec.X509EncodedKeySpec bobPubKeySpec = new java.security.spec.X509EncodedKeySpec(

    pk.getEncoded());

    return keyf.generatePublic(bobPubKeySpec);

    }

    至于openssl我就不再做介绍,网上有很多资料,而且它本身的文档也很齐全

    在后面附上一些相关的类,  SignProvider.java 端负责公钥转换和加签验签     Base64.java负责64为编码    fcOpenSslRef.rar---Openssl相关类

    注:本人对c++也不熟,所以上面的一些c++代码只做参考。

    原文:http://www.chlusoft.com/tech/347.jhtml

  • 相关阅读:
    Vue.js依赖收集
    Vue.js响应式原理
    详解.Net 如何上传自己的包到Nuget平台以及如何使用Nuget包管理器
    利用docker容器运行.net core webapi
    wpf mvvm datagrid DataGridTemplateColumn的绑定无效的可能原因之一!
    算法之A星算法(寻路)
    Python 学习日记 第一天
    Python 学习日记 第三天
    Python 学习日记 第二天
    再做一题,2013616更新
  • 原文地址:https://www.cnblogs.com/davidwang456/p/3922508.html
Copyright © 2020-2023  润新知