数字签名及验证


由于项目需要用到数字签名,所以就上网查看了一些资料,随便找就是一大堆,说的也都差不多,自己写写关于数字签名这块记录,当做笔记吧.

首先说几个概念签名与加密.可以参考这个博客https://my.oschina.net/u/916545/blog/653201

签名的模式主要是:    1、甲方构造密钥对(公钥+私钥),并且将公钥给乙方

  2、甲方使用私钥对数据进行签名,然后将“签名+数据” 发送给乙方 

  3、乙方使用公钥+数字签名 验证数据

这里不多说了直接上代码解释

    //数字签名,密钥算法
    public static final String KEY_ALGORITHM="RSA";

    /**
     * 数字签名
     * 签名/验证算法
     * */
    public static final String SIGNATURE_ALGORITHM="SHA1withRSA";

    /**
     * RSA密钥长度,RSA算法的默认密钥长度是1024
     * 密钥长度必须是64的倍数,在512到65536位之间
     * */
    private static final int KEY_SIZE=1024;
    //公钥
    private static final String PUBLIC_KEY="RSAPublicKey";
    //私钥
    private static final String PRIVATE_KEY="RSAPrivateKey";

    /**
     * 获取私钥  传入bese64String字符串
     * */
    public static PrivateKey getPrivateKey(String privateKeyBase64Str) throws Exception{
        //取得私钥Base64.decode(privateKeyBase64Str,Base64.DEFAULT)
        PKCS8EncodedKeySpec sPkcs8KeySpec= new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyBase64Str));

        KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM);
        //生成私钥
        return  keyFactory.generatePrivate(sPkcs8KeySpec);
    }

    /**
     * 签名
     * @param content
     * 待签名数据
     * @param privateKeyBase64Str 密钥
     * @return byte[] 数字签名
     * */
    public static String sign(String content,String privateKeyBase64Str) throws Exception{
        System.out.println(Base64.class);
        //取得私钥Base64.decode(privateKeyBase64Str,Base64.DEFAULT)
        PKCS8EncodedKeySpec sPkcs8KeySpec= new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyBase64Str.getBytes()));
        KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM);
        PrivateKey privateKey = keyFactory.generatePrivate(sPkcs8KeySpec);
        //实例化Signature
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        //初始化Signature
        signature.initSign(privateKey);
        //更新
        signature.update(content.getBytes());
//        return signature.sign();   //

        String Signh=new String(Hex.encodeHex(signature.sign())) ;

        return Signh;
    }



/*    public static byte[] sign(String content,PrivateKey privateKey) throws Exception{
        //实例化Signature
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        //初始化Signature
        signature.initSign(privateKey);
        //更新
        signature.update(content.getBytes());
        return signature.sign();   //
    }*/

    //*----------------------------------------------------------*//

    public static PublicKey getPublicKey(String publicKeyBase64Str ) throws Exception{
        //转换公钥材料
        //实例化密钥工厂
        KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM);
        //初始化公钥
        //密钥材料转换
        X509EncodedKeySpec x509KeySpec=new X509EncodedKeySpec(Base64.decodeBase64(publicKeyBase64Str));
        //产生公钥
        PublicKey pubKey=keyFactory.generatePublic(x509KeySpec);
        return pubKey;
    }

    /**
     * 校验数字签名
     * @param content 待校验数据
     * @param publicKey 公钥
     * @param signHexStr 数字签名
     * @return boolean 校验成功返回true,失败返回false
     * */
    public static boolean verify(String content,String signHexStr,PublicKey publicKey) throws Exception{
        //实例化Signature
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        //初始化Signature
        signature.initVerify(publicKey);
        //更新
        signature.update(content.getBytes());
        //验证
        return signature.verify(Hex.decodeHex(signHexStr.toCharArray()));
    }
    public static boolean verify(String content,String signHexStr,String publicKeyBase64Str ) throws Exception{
        //转换公钥材料
        //实例化密钥工厂
        KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM);
        //初始化公钥//密钥材料转换
        X509EncodedKeySpec x509KeySpec=new X509EncodedKeySpec(Base64.decodeBase64(publicKeyBase64Str.getBytes()));
        //产生公钥
        PublicKey pubKey=keyFactory.generatePublic(x509KeySpec);

        //实例化Signature
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        //初始化Signature
        signature.initVerify(pubKey);
        //更新
        signature.update(content.getBytes());
        //验证
        return signature.verify(Hex.decodeHex(signHexStr.toCharArray()));
    }

这里我是直接从存储介质上拿到的私钥,私钥是后台给我的,

我使用私钥进行数字签名,后台进行验证,但后台在使用时指定了一些规定导致我一直解不出来,最后使用

Commons Codecjar包,

从上可以看到在拿到prikey( 存储介质读取),使用sign方法进行签名,需要对传入的privateKeyBase64Str进行解码,由于一直使用安卓base64Api无法解出正确格式,使用commons code-jar包,里面的base64就可正常,弹药注意使用正确的方法,要不然会报没有此方法,Base64.decodeBase64(privateKeyBase64Str)就不行了
其他方法类似
签名验证就使用verify方法.初次写博客还有许多不懂的,上面的内容也是仅供参考,如果有不对的请帮我指出,感谢大家.





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值