Java密码学 非对称加密以及使用secp256k1进行数字签名(ECDSA),也适合Android(下)

1. 概述


上篇讲述了秘钥的生成、存储和加载,这篇的内容就是如何生成和校验数字签名。

2. Signature类


在Java中,签名和校验,都是通过: Signature 类来实现的。

该类的主要方法如下:

  • getInstance(String algorithm)

工厂方法,获取Signature实例,而参数:algorithm就是签名算法的名称,这里我们使用的是:SHA256withECDSA

更具体的参数,请浏览:https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#Signature

  • initSign(PrivateKey privateKey)
  • initVerify(PublicKey publicKey)

初始化成签名或者校验,Signature类的实例,在同一个阶段只能完成签名或者校验之一的任务,因此调用initSign或者initVeify让Signature进入相应的状态

  • update(byte[] data)

无论是计算签名,还是校验数据,都需要传入被签名或者被校验的数据,调用该方法进行计算。注意,该方法可以调用多次,通常数据都可能非常大,不可能一次性读入内存(从磁盘上或者网络),因此我们可以对数据进行分块,一次性一KB或者合适的块进行多次调用

  • sign()

获取签名,当所有的数据都调用update计算后,就可以获取签名了,返回的签名是一个byte数组

  • verify(byte[] signature)

校验签名,当所有的数据都调用update计算之后,调用该方法,传递签名数据,如果签名正确,那么返回true,否则返回false,说明数据可能被篡改、伪造,或者对应的私钥不正确。

3. 实例


Java中计算签名比较简单,请阅读下面代码中的注释

public static byte[] signData(String algorithm, byte[] data, PrivateKey key) throws Exception {
        Signature signer = Signature.getInstance(algorithm);
        signer.initSign(key);
        signer.update(data);
        return (signer.sign());
    }

    public static boolean verifySign(String algorithm, byte[] data, PublicKey key, byte[] sig) throws Exception {
        Signature signer = Signature.getInstance(algorithm);
        signer.initVerify(key);
        signer.update(data);
        return (signer.verify(sig));
    }

    @Test
    public void testSignVerify() throws Exception {
        // 需要签名的数据
        byte[] data = new byte[1000];
        for (int i=0; i

我们在测试用例中可以看到,只要是数据、签名被修改,或者不正确的私钥都会引发签名验证失败.

4. 签名输出数据解析


针对 SHA256withECDSA ,输出的是DER编码的签名数据,长度并非固定,但是是70到72字节,之所以会这样是因为,SHA256withECDSA 签名输出实际是两个32字节的大整数(r和s),在转换成byte[]的时候,如果为负数,那么会添加前导位0,如果当r和s都是正数,那么就是64个字节,都是负数,就是66字节。而DER编码还会包含类型以及长度字段,因此总长度就会到70到72字节。一般情况下,传输DER编码的签名值没多大问题,但如果对数据量要求十分严格,例如在BLE上传输,可以提取出r和s再打包传输

5. 参考


  1. Java SE 7 Security Documentation
  2. 数字签名是什么?
  3. Android签名机制之---签名过程详解
  4. ECC加密算法入门介绍

你可能感兴趣的:(Java密码学 非对称加密以及使用secp256k1进行数字签名(ECDSA),也适合Android(下))