All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.zhangxd1989.basetool.crypto.asymmetric.Sign Maven / Gradle / Ivy

There is a newer version: 1.0.16
Show newest version
package com.github.zhangxd1989.basetool.crypto.asymmetric;

import com.github.zhangxd1989.basetool.codec.Base64;
import com.github.zhangxd1989.basetool.collection.CollectionUtil;
import com.github.zhangxd1989.basetool.crypto.CryptoException;
import com.github.zhangxd1989.basetool.crypto.SecureUtil;

import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Set;

/**
 * 签名包装,{@link Signature} 包装类
 *
 * @author sheldon
 */
public class Sign extends BaseAsymmetric {

    /**
     * 签名,用于签名和验证
     */
    protected Signature signature;

    /**
     * 构造,创建新的私钥公钥对
     *
     * @param algorithm {@link SignAlgorithm}
     */
    public Sign(SignAlgorithm algorithm) {
        this(algorithm, (byte[]) null, (byte[]) null);
    }

    /**
     * 构造,创建新的私钥公钥对
     *
     * @param algorithm 算法
     */
    public Sign(String algorithm) {
        this(algorithm, (byte[]) null, (byte[]) null);
    }

    /**
     * 构造 私钥和公钥同时为空时生成一对新的私钥和公钥
* 私钥和公钥可以单独传入一个,如此则只能使用此钥匙来做签名或验证 * * @param algorithm {@link SignAlgorithm} * @param privateKeyStr 私钥Hex或Base64表示 * @param publicKeyStr 公钥Hex或Base64表示 */ public Sign(SignAlgorithm algorithm, String privateKeyStr, String publicKeyStr) { this(algorithm.getValue(), SecureUtil.decode(privateKeyStr), SecureUtil.decode(publicKeyStr)); } /** * 构造 私钥和公钥同时为空时生成一对新的私钥和公钥
* 私钥和公钥可以单独传入一个,如此则只能使用此钥匙来做签名或验证 * * @param algorithm {@link SignAlgorithm} * @param privateKey 私钥 * @param publicKey 公钥 */ public Sign(SignAlgorithm algorithm, byte[] privateKey, byte[] publicKey) { this(algorithm.getValue(), privateKey, publicKey); } /** * 构造 私钥和公钥同时为空时生成一对新的私钥和公钥
* 私钥和公钥可以单独传入一个,如此则只能使用此钥匙来做签名或验证 * * @param algorithm {@link SignAlgorithm} * @param keyPair 密钥对(包括公钥和私钥) */ public Sign(SignAlgorithm algorithm, KeyPair keyPair) { this(algorithm.getValue(), keyPair); } /** * 构造 私钥和公钥同时为空时生成一对新的私钥和公钥
* 私钥和公钥可以单独传入一个,如此则只能使用此钥匙来做签名或验证 * * @param algorithm {@link SignAlgorithm} * @param privateKey 私钥 * @param publicKey 公钥 */ public Sign(SignAlgorithm algorithm, PrivateKey privateKey, PublicKey publicKey) { this(algorithm.getValue(), privateKey, publicKey); } /** * 构造 私钥和公钥同时为空时生成一对新的私钥和公钥
* 私钥和公钥可以单独传入一个,如此则只能使用此钥匙来做签名或验证 * * @param algorithm 非对称加密算法 * @param privateKeyBase64 私钥Base64 * @param publicKeyBase64 公钥Base64 */ public Sign(String algorithm, String privateKeyBase64, String publicKeyBase64) { this(algorithm, Base64.decode(privateKeyBase64), Base64.decode(publicKeyBase64)); } /** * 构造 *

* 私钥和公钥同时为空时生成一对新的私钥和公钥
* 私钥和公钥可以单独传入一个,如此则只能使用此钥匙来做签名或验证 * * @param algorithm 算法 * @param privateKey 私钥 * @param publicKey 公钥 */ public Sign(String algorithm, byte[] privateKey, byte[] publicKey) { this(algorithm, SecureUtil.generatePrivateKey(algorithm, privateKey), SecureUtil.generatePublicKey(algorithm, publicKey) ); } /** * 构造 私钥和公钥同时为空时生成一对新的私钥和公钥
* 私钥和公钥可以单独传入一个,如此则只能使用此钥匙来做签名或验证 * * @param algorithm 算法,见{@link SignAlgorithm} * @param keyPair 密钥对(包括公钥和私钥) */ public Sign(String algorithm, KeyPair keyPair) { this(algorithm, keyPair.getPrivate(), keyPair.getPublic()); } /** * 构造 *

* 私钥和公钥同时为空时生成一对新的私钥和公钥
* 私钥和公钥可以单独传入一个,如此则只能使用此钥匙来做签名或验证 * * @param algorithm 算法 * @param privateKey 私钥 * @param publicKey 公钥 */ public Sign(String algorithm, PrivateKey privateKey, PublicKey publicKey) { super(algorithm, privateKey, publicKey); } /** * 初始化 * * @param algorithm 算法 * @param privateKey 私钥 * @param publicKey 公钥 * @return this */ @Override public Sign init(String algorithm, PrivateKey privateKey, PublicKey publicKey) { try { signature = Signature.getInstance(algorithm); } catch (NoSuchAlgorithmException e) { throw new CryptoException(e); } super.init(algorithm, privateKey, publicKey); return this; } /** * 用私钥对信息生成数字签名 * * @param data 加密数据 * @return 签名 */ public byte[] sign(byte[] data) { lock.lock(); try { signature.initSign(this.privateKey); signature.update(data); return signature.sign(); } catch (Exception e) { throw new CryptoException(e); } finally { lock.unlock(); } } /** * 用公钥检验数字签名的合法性 * * @param data 数据 * @param sign 签名 * @return 是否验证通过 */ public boolean verify(byte[] data, byte[] sign) { lock.lock(); try { signature.initVerify(this.publicKey); signature.update(data); return signature.verify(sign); } catch (Exception e) { throw new CryptoException(e); } finally { lock.unlock(); } } /** * 获得签名对象 * * @return {@link Signature} */ public Signature getSignature() { return signature; } /** * 设置签名 * * @param signature 签名对象 {@link Signature} * @return 自身 {@link AsymmetricCrypto} */ public Sign setSignature(Signature signature) { this.signature = signature; return this; } /** * 设置{@link Certificate} 为PublicKey
* 如果Certificate是X509Certificate,我们需要检查是否有密钥扩展 * * @param certificate {@link Certificate} * @return this */ public Sign setCertificate(Certificate certificate) { // If the certificate is of type X509Certificate, // we should check whether it has a Key Usage // extension marked as critical. if (certificate instanceof X509Certificate) { // Check whether the cert has a key usage extension // marked as a critical extension. // The OID for KeyUsage extension is 2.5.29.15. final X509Certificate cert = (X509Certificate) certificate; final Set critSet = cert.getCriticalExtensionOIDs(); if (CollectionUtil.isNotEmpty(critSet) && critSet.contains("2.5.29.15")) { final boolean[] keyUsageInfo = cert.getKeyUsage(); // keyUsageInfo[0] is for digitalSignature. if ((keyUsageInfo != null) && (!keyUsageInfo[0])) { throw new CryptoException("Wrong key usage"); } } } this.publicKey = certificate.getPublicKey(); return this; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy