密码学模块

标签:java-sdk Crypto


Java SDK提供了可访问所有密码学相关接口的CryptoSuiteCryptoSuite会根据传入的cryptoType(目前支持CryptoType.ECDSA_TYPECryptoType.SM_TYPE,前者用在非国密链中,后者用于国密链中)初始化密码学相关的套件。

Java SDK目前支持以下功能:

  • 计算哈希: 支持sm3keccak256两种哈希算法,一般国密采用前者,非国密采用后者;

  • 签名/验签 : 支持sm2secp256k1两种签名和验签方法,一般国密采用前者,非国密采用后者。

创建CryptoSuite

Java SDK目前支持创建非国密、国密类型的CryptoSuite

创建非国密类型的CryptoSuite的示例如下:

    public CryptoSuite createECDSACryptoSuite()
    {
        return new CryptoSuite(CryptoType.ECDSA_TYPE);
    }

创建国密类型的CryptoSuite的示例如下:

  public CryptoSuite createSMCryptoSuite()
    {
        return new CryptoSuite(CryptoType.SM_TYPE);
    }

哈希接口

初始化密码学套件CryptoSuite后,用户可直接使用创建的CryptoSuite调用哈希接口,也可自定义创建指定的哈希类,并调用哈希算法。

使用CryptoSuite调用哈希接口

    // 调用keccak256哈希算法(入参为String)
    public String calculateHashWithkeccak256(String data)
    {
        // 创建非国密的CryptoSuite
        CryptoSuite cryptoSuite = new CryptoSuite(CryptoType.ECDSA_TYPE);
        // 使用cryptoSuite调用hash算法,返回十六进制哈希字符串
        return cryptoSuite.hash(data);
    }

    // 调用keccak256哈希算法(入参为byte[])
    public byte[] calculateHashWithkeccak256(byte[] data)
    {
        // 创建非国密的CryptoSuite
        CryptoSuite cryptoSuite = new CryptoSuite(CryptoType.ECDSA_TYPE);
        // 使用cryptoSuite调用hash算法
        // 返回二进制数组,可通过Hex.toHexString(result)将其转换成十六进制字符串
        byte[] result = cryptoSuite.hash(data);
        return result;
    }

    // 调用sm3哈希算法(入参为String)
    public String calculateHashWithSM3(String data)
    {
        // 创建国密的CryptoSuite
        CryptoSuite SMcryptoSuite = new CryptoSuite(CryptoType.SM_TYPE);
        // 使用SMcryptoSuite调用hash算法,返回十六进制哈希字符串
        return SMcryptoSuite.hash(data);
    }

    // 调用sm3哈希算法(入参为byte[])
    public byte[] calculateHashWithSM3(byte[] data)
    {
         // 创建非国密的CryptoSuite
        CryptoSuite SMcryptoSuite = new CryptoSuite(CryptoType.SM_TYPE);
        // 使用SMcryptoSuite调用hash算法
        // 返回二进制数组,可通过Hex.toHexString(result)将其转换成十六进制字符串
        byte[] result = SMcryptoSuite.hash(data);
        return result;
    }

创建指定方法的哈希对象调用哈希接口

    /// 调用keccak256哈希算法(入参为String)
    public String calculateHashWithkeccak256(String data)
    {
        // 创建keccak256对应的对象
        Keccak256 hasher = new Keccak256();
        // 返回十六进制哈希字符串
        return hasher.hash(data);
    }

    /// 调用keccak256哈希算法(入参为byte[])
    public byte[] calculateHashWithkeccak256(byte[] data)
    {
        // 创建keccak256对应的对象
        Keccak256 hasher = new Keccak256();
        // 返回二进制数组,可通过Hex.toHexString将其转换为十六进制字符串
        return hasher.hash(data);
    }

    // 调用sm3哈希算法(入参为String)
    public String calculateHashWithSM3(String data)
    {
        // 创建sm3对应的对象
        SM3Hash hasher = new SM3Hash();
        // 返回十六进制哈希字符串
        return hasher.hash(data);
    }

    // 调用sm3哈希算法(入参为byte[])
    public byte[] calculateHashWithSM3(byte[] data)
    {
        // 创建sm3对应的对象
        SM3Hash hasher = new SM3Hash();
        // 返回二进制数组,可通过Hex.toHexString将其转换为十六进制字符串
        return hasher.hash(data);
    }

签名/验签接口

初始化密码学套件CryptoSuite后,用户可直接使用创建的CryptoSuite调用签名和验签接口,也可自定义创建指定的签名验签对象,调用签名和验签接口。

注解

签名/验签接口传入的明文数据必须是哈希,生成指定明文的签名前,须计算其哈希,并将哈希结果作为签名原文传入接口生成签名

使用CryptoSuite调用签名/验签接口

非国密签名/验签接口调用示例如下:

    // 生成secp256k1签名(入参为String)
    public ECDSASignatureResult  generateSigantureWithSecp256k1(String data)
    {
        CryptoSuite cryptoSuite = new CryptoSuite(CryptoType.ECDSA_TYPE);
        // 生成CryptoKeyPair
        CryptoKeyPair cryptoKeyPair = cryptoSuite.createKeyPair();
        // 计算传入数据的哈希(keccak256哈希算法)
        String hashData = cryptoSuite.hash(data);
        // 生成签名
        return (ECDSASignatureResult)(cryptoSuite.sign(hashData, cryptoKeyPair));
    }

    // 生成secp256k1签名(入参为byte[])
    public ECDSASignatureResult generateSigantureWithSecp256k1(byte[] data)
    {
        CryptoSuite cryptoSuite = new CryptoSuite(CryptoType.ECDSA_TYPE);
        // 生成CryptoKeyPair
        CryptoKeyPair cryptoKeyPair = cryptoSuite.createKeyPair();
        // 计算传入数据的哈希(keccak256哈希算法)
        byte[] hashData = cryptoSuite.hash(data);
        // 生成签名
        return (ECDSASignatureResult)(cryptoSuite.sign(hashData, cryptoKeyPair));
    }

    // 验证secp256k1签名(入参为String)
    public boolean verifySignature(SignatureResult signatureResult, CryptoKeyPair keyPair, String data)
    {
        CryptoSuite cryptoSuite = new CryptoSuite(CryptoType.ECDSA_TYPE);
        // 计算data的哈希(keccak256k1哈希算法)
        String hashData = cryptoSuite.hash(data);
        // 验证签名
        return cryptoSuite.verify(keyPair.getHexPublicKey(), hashData, signatureResult.convertToString());
    }

    // 验证secp256k1签名(入参为byte[])
    public boolean verifySignature(SignatureResult signatureResult, CryptoKeyPair keyPair, byte[] data)
    {
        CryptoSuite cryptoSuite = new CryptoSuite(CryptoType.ECDSA_TYPE);
        // 计算data的哈希(keccak256k1哈希算法)
        byte[] hashData = cryptoSuite.hash(data);
        // 验证签名
        return cryptoSuite.verify(keyPair.getHexPublicKey(), hashData, signatureResult.getSignatureBytes());
    }

类似地,国密签名/验签接口调用示例如下:

    // 生成sm2签名(入参为String)
    public SM2SignatureResult  generateSigantureWithSM2(String data)
    {
        CryptoSuite cryptoSuite = new CryptoSuite(CryptoType.SM_TYPE);
        // 生成CryptoKeyPair
        CryptoKeyPair cryptoKeyPair = cryptoSuite.createKeyPair();
        // 计算传入数据的哈希(sm3哈希算法)
        String hashData = cryptoSuite.hash(data);
        // 生成签名
        return (SM2SignatureResult)(cryptoSuite.sign(hashData, cryptoKeyPair));
    }

    // 生成sm2签名(入参为byte[])
    public SM2SignatureResult generateSigantureWithSM2(byte[] data)
    {
        CryptoSuite cryptoSuite = new CryptoSuite(CryptoType.SM_TYPE);
        // 生成CryptoKeyPair
        CryptoKeyPair cryptoKeyPair = cryptoSuite.createKeyPair();
        // 计算传入数据的哈希(sm3哈希算法)
        byte[] hashData = cryptoSuite.hash(data);
        // 生成签名
        return (SM2SignatureResult)(cryptoSuite.sign(hashData, cryptoKeyPair));
    }

    // 验证sm2签名(入参为String)
    public boolean verifySignature(SignatureResult signatureResult, CryptoKeyPair keyPair, String data)
    {
        CryptoSuite cryptoSuite = new CryptoSuite(CryptoType.SM_TYPE);
        // 计算data的哈希(sm3哈希算法)
        String hashData = cryptoSuite.hash(data);
        // 验证签名
        return cryptoSuite.verify(keyPair.getHexPublicKey(), hashData, signatureResult.convertToString());
    }
    
    // 验证sm2签名(入参为byte[])
    public boolean verifySignature(SignatureResult signatureResult, CryptoKeyPair keyPair, byte[] data)
    {
        CryptoSuite cryptoSuite = new CryptoSuite(CryptoType.SM_TYPE);
        // 计算data的哈希(sm3哈希算法)
        byte[] hashData = cryptoSuite.hash(data);
        // 验证签名
        return cryptoSuite.verify(keyPair.getHexPublicKey(),  Hex.toHexString(hashData), signatureResult.convertToString());
    }

创建指定方法的签名验签对象调用签名验签接口

非国密签名/验签接口调用示例如下(签名密钥对的生成可参考这里):

    // 生成secp256k1签名(入参为String)
    public ECDSASignatureResult generateSignatureWithSecp256k1(CryptoKeyPair ecdsaKeyPair, String data)
    {
        // 生成secp256k1签名对象
        ECDSASignature signer = new ECDSASignature();
        // 计算data的哈希(keccak256)
        Keccak256 hasher = new Keccak256();
        String hashData = hasher.hash(data);
        return (ECDSASignatureResult)signer.sign(hashData, ecdsaKeyPair);
    }

    // 生成secp256k1签名(入参为byte[])
    public ECDSASignatureResult generateSignatureWithSecp256k1(CryptoKeyPair ecdsaKeyPair, byte[] data)
    {
        // 生成secp256k1签名对象
        ECDSASignature signer = new ECDSASignature();
        // 计算data的哈希(keccak256)
        Keccak256 hasher = new Keccak256();
        byte[] hashData = hasher.hash(data);
        return (ECDSASignatureResult)signer.sign(hashData, ecdsaKeyPair);
    }

    // 验证secp256k1签名(入参为String)
    public boolean verifySignature(SignatureResult signatureResult, CryptoKeyPair ecdsaKeyPair, String data)
    {
        // 生成secp256k1验签对象
        ECDSASignature verifier = new ECDSASignature();
        // 计算data的哈希(keccak256)
        Keccak256 hasher = new Keccak256();
        String hashData = hasher.hash(data);
        // 验证签名
        return verifier.verify(ecdsaKeyPair.getHexPublicKey(), hashData, signatureResult.convertToString());
    }
    
    // 验证secp256k1签名(入参为byte[])
    public boolean verifySignature(SignatureResult signatureResult, CryptoKeyPair ecdsaKeyPair, byte[] data)
    {
        // 生成secp256k1验签对象
        ECDSASignature verifier = new ECDSASignature();
        // 计算data的哈希
        Keccak256 hasher = new Keccak256();
        byte[] hashData = hasher.hash(data);
        // 验证签名
        return verifier.verify(ecdsaKeyPair.getHexPublicKey(), Hex.toHexString(hashData), signatureResult.convertToString());
    }

类似地,国密签名/验签接口调用示例如下:

    // 生成sm2签名(入参为String)
    public SM2SignatureResult generateSignatureWithSM2(CryptoKeyPair sm2KeyPair, String data)
    {
        // 生成sm2签名对象
        SM2Signature signer = new SM2Signature();
        // 计算data的哈希(sm3)
        SM3Hash hasher = new SM3Hash();
        String hashData = hasher.hash(data);
        return (SM2SignatureResult)signer.sign(hashData, sm2KeyPair);
    }

    // 生成sm2签名(入参为byte[])
    public SM2SignatureResult generateSignatureWithSecp256k1(CryptoKeyPair sm2KeyPair, byte[] data)
    {
        // 生成sm2签名对象
        SM2Signature signer = new SM2Signature();
        // 计算data的哈希(sm3)
        SM3Hash hasher = new SM3Hash();
        byte[] hashData = hasher.hash(data);
        return (SM2SignatureResult)signer.sign(hashData, sm2KeyPair);
    }

    // 验证sm2签名(入参为String)
    public boolean verifySignature(SignatureResult signatureResult, CryptoKeyPair sm2KeyPair, String data)
    {
        // 生成sm2验签对象
        SM2Signature verifier = new SM2Signature();
        // 计算data的哈希
        SM3Hash hasher = new SM3Hash();
        String hashData = hasher.hash(data);
        // 验证签名
        return verifier.verify(sm2KeyPair.getHexPublicKey(), hashData, signatureResult.convertToString());
    }

    // 验证sm2签名(入参为byte[])
    public boolean verifySignature(SignatureResult signatureResult, CryptoKeyPair sm2KeyPair, byte[] data)
    {
        // 生成sm2验签对象
        SM2Signature verifier = new SM2Signature();
        // 计算data的哈希
        SM3Hash hasher = new SM3Hash();
        byte[] hashData = hasher.hash(data);
        // 验证签名
        return verifier.verify(sm2KeyPair.getHexPublicKey(), Hex.toHexString(hashData), signatureResult.convertToString());
    }

签名结果类型转换

Java SDK提供了将签名结果SignatureResult转换为字符串,以及从字符串中构造签名对象SignatureResult的功能,示例如下:

    // 将签名结果转换为字符串
    public String covertSignatureResultToString(SignatureResult signatureResult)
    {
        return signatureResult.convertToString();
    }

    // 从字符串中构造非国密签名对象
    public ECDSASignatureResult covertStringToECDSASignatureResult(String signatureString)
    {
        return new ECDSASignatureResult(signatureString);
    }

    // 从签名字符串中构造国密签名对象
    public SM2SignatureResult covertStringToSM2SignatureResult(CryptoKeyPair smKeyPair, String signatureString)
    {
        return new SM2SignatureResult(smKeyPair.getHexPublicKey(), signatureString);
    }