栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

非对称加密 DSA算法

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

非对称加密 DSA算法

原理

数字签名算法(DSA - Digital Signature Algorithm)是用于数字签名的算法,基于模算数和离散对数的复杂度。DSA是Schnorr和ElGamal签名方案的变体。

DSA 算法包含了四种操作:密钥生成、密钥分发、签名、验证

    密钥生成

密钥生成包含两个阶段。第一阶段是算法参数的选择,可以在系统的不同用户之间共享,而第二阶段则为每个用户计算独立的密钥组合。

    密钥分发

签名者需要透过可信任的管道发布公钥 y,并且安全地保护 x 不被其他人知道。

    签名流程

    验证签名


下列密码学库有提供 DSA 的支持:

OpenSSLGnuTLSwolfCryptCrypto++cryptlibBotanBouncy CastlelibgcryptNettle

数据来源 – 维基百科

Java jdk实现

DsaUtils.java

package crypto.dsa;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;


public class DsaUtils {

    private static final String ALGORITHM = "DSA";

    
    private static final String DEFAULT_SIGNATURE_ALGORITHM = "SHA1withDSA";

    
    private static final int DEFAULT_KEY_SIZE = 1024;

    
    public static InnerKey generateKey() throws NoSuchAlgorithmException {
        return generateKey(DEFAULT_KEY_SIZE);
    }

    
    public static InnerKey generateKey(int keysize) throws NoSuchAlgorithmException {
        // 初始化密钥
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);
        keyPairGenerator.initialize(keysize);

        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        //DSAPublicKey dsaPublicKey = (DSAPublicKey) keyPair.getPublic();
        //DSAPrivateKey dsaPrivateKey = (DSAPrivateKey) keyPair.getPrivate();
        return InnerKey.builder()
                .publicKey(keyPair.getPublic().getEncoded())
                .privateKey(keyPair.getPrivate().getEncoded())
                .build();
    }

    public static byte[] sign(byte[] privateKey, byte[] data)
            throws InvalidKeySpecException, NoSuchAlgorithmException, InvalidKeyException, SignatureException {
        return sign(privateKey, data, DEFAULT_SIGNATURE_ALGORITHM);
    }

    
    public static byte[] sign(byte[] privateKey, byte[] data, String signatureAlgorithm)
            throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException {
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);

        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey);
        PrivateKey privateKey2 = keyFactory.generatePrivate(pkcs8EncodedKeySpec);

        Signature signature = Signature.getInstance(signatureAlgorithm);
        signature.initSign(privateKey2);
        signature.update(data);
        byte[] bytes = signature.sign();
        return bytes;
    }

    public static boolean verifySign(byte[] publicKey, byte[] data, byte[] sign)
            throws InvalidKeySpecException, NoSuchAlgorithmException, InvalidKeyException, SignatureException {
        return verifySign(publicKey, data, sign, DEFAULT_SIGNATURE_ALGORITHM);
    }

    
    public static boolean verifySign(byte[] publicKey, byte[] data, byte[] sign, String signatureAlgorithm)
            throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException {
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);

        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKey);
        PublicKey publicKey2 = keyFactory.generatePublic(x509EncodedKeySpec);

        Signature signature = Signature.getInstance(signatureAlgorithm);
        signature.initVerify(publicKey2);
        signature.update(data);
        boolean bool = signature.verify(sign);
        return bool;
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class InnerKey {
        private byte[] publicKey;
        private byte[] privateKey;
    }
}

测试代码

package crypto.dsa;

import org.apache.commons.codec.binary.base64;

public class DsaUtilsTest {

    public static void main(String[] args) throws Exception {
        String text = "你好世界 DSA签名";
        DsaUtils.InnerKey innerKey = DsaUtils.generateKey();
        System.out.println("公钥:" + base64.encodebase64String(innerKey.getPublicKey()));
        System.out.println("私钥:" + base64.encodebase64String(innerKey.getPrivateKey()));

        byte[] sign = DsaUtils.sign(innerKey.getPrivateKey(), text.getBytes());
        System.out.println("原文:" + text);
        System.out.println("数字签名:" + base64.encodebase64String(sign));
        boolean bool = DsaUtils.verifySign(innerKey.getPublicKey(), text.getBytes(), sign);
        System.out.println("验签结果:" + bool);
    }
}
Java jdk实现 ECDSA
package crypto.dsa;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

public class EcDsaUtils {

    private static final String ALGORITHM = "EC";

    
    public static final String DEFAULT_SIGNATURE_ALGORITHM = "SHA1withECDSA";

    public enum SignatureAlgorithm {
        NONEwithECDSA,
        SHA1withECDSA,
        SHA224withECDSA,
        SHA256withECDSA,
        SHA384withECDSA,
        SHA512withECDSA
    }

    public static InnerKey generateKey() throws Exception {
        return generateKey(256);
    }

    
    public static InnerKey generateKey(int keySize) throws Exception {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);
        keyPairGenerator.initialize(keySize);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        //ECPublicKey ecPublicKey = (ECPublicKey) keyPair.getPublic();
        //ECPrivateKey ecPrivateKey = (ECPrivateKey) keyPair.getPrivate();
        return InnerKey.builder()
                .publicKey(keyPair.getPublic().getEncoded())
                .privateKey(keyPair.getPrivate().getEncoded())
                .build();
    }

    public static byte[] sign(byte[] privateKey, byte[] data) throws Exception {
        return sign(privateKey, data, DEFAULT_SIGNATURE_ALGORITHM);
    }

    
    public static byte[] sign(byte[] privateKey, byte[] data, String algorithm) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);

        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey);
        PrivateKey privateKey2 = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        Signature signature = Signature.getInstance(algorithm);
        signature.initSign(privateKey2);
        signature.update(data);
        return signature.sign();
    }

    public static boolean verifySign(byte[] publicKey, byte[] data, byte[] sign) throws Exception {
        return verifySign(publicKey, data, sign, DEFAULT_SIGNATURE_ALGORITHM);
    }

    
    public static boolean verifySign(byte[] publicKey, byte[] data, byte[] sign, String algorithm) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);

        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKey);
        PublicKey publicKey2 = keyFactory.generatePublic(x509EncodedKeySpec);

        Signature signature = Signature.getInstance(algorithm);
        signature.initVerify(publicKey2);
        signature.update(data);
        return signature.verify(sign);
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class InnerKey {
        private byte[] publicKey;
        private byte[] privateKey;
    }
}

package crypto.dsa;

import org.apache.commons.codec.binary.base64;

public class EcDsaUtilsTest {

    public static void main(String[] args) throws Exception {
        String text = "你好世界 ECDSA签名";
        EcDsaUtils.InnerKey innerKey = EcDsaUtils.generateKey(112);
        System.out.println("公钥:" + base64.encodebase64String(innerKey.getPublicKey()));
        System.out.println("私钥:" + base64.encodebase64String(innerKey.getPrivateKey()));

        byte[] sign = EcDsaUtils.sign(innerKey.getPrivateKey(), text.getBytes(),
                EcDsaUtils.SignatureAlgorithm.SHA224withECDSA.name());
        System.out.println("原文:" + text);
        System.out.println("数字签名:" + base64.encodebase64String(sign));
        boolean bool = EcDsaUtils.verifySign(innerKey.getPublicKey(), text.getBytes(), sign,
                EcDsaUtils.SignatureAlgorithm.SHA224withECDSA.name());
        System.out.println(bool);
    }
}

code

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/781329.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号