原理

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

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

  1. 密钥生成

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

  1. 密钥分发

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

  1. 签名流程

  1. 验证签名


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

  • OpenSSL
  • GnuTLS
  • wolfCrypt
  • Crypto++
  • cryptlib
  • Botan
  • Bouncy Castle
  • libgcrypt
  • Nettle

数据来源 – 维基百科

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;/*** 非对称加密 DSA 不能用于加密数据,只能用于数字签名*/
public class DsaUtils {private static final String ALGORITHM = "DSA";/*** @link {https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Signature}*/private static final String DEFAULT_SIGNATURE_ALGORITHM = "SHA1withDSA";/*** This must be a multiple of 64, ranging from 512 to 1024 (inclusive), or 2048. The default keysize is 1024.*/private static final int DEFAULT_KEY_SIZE = 1024;/*** 生成密钥对** @link {https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyPairGenerator}*/public static InnerKey generateKey() throws NoSuchAlgorithmException {return generateKey(DEFAULT_KEY_SIZE);}/*** 生成密钥对** @param keysize* @return* @throws NoSuchAlgorithmException*/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);}/*** 使用私钥进行签名** @param privateKey         私钥* @param data               数据* @param signatureAlgorithm 签名算法* @return* @throws Exception*/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);}/*** 使用公钥验证签名** @param publicKey          公钥* @param data               数据* @param sign               数据签名* @param signatureAlgorithm 签名算法* @return* @throws Exception*/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@Builderpublic 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";/*** NONEwithECDSA* SHA1withECDSA* SHA224withECDSA* SHA256withECDSA* SHA384withECDSA* SHA512withECDSA** @link {https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Signature}*/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);}/*** 初始化密钥** @param keySize Keysize must range from 112 to 571 (inclusive).* @return* @throws Exception* @link {https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html#SunEC}*/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);}/*** 执行签名** @param privateKey 私钥* @param data       数据* @param algorithm  签名算法 {@link SignatureAlgorithm}* @return* @throws Exception*/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);}/*** 验证签名** @param publicKey 公钥* @param data      数据* @param sign      数据签名* @param algorithm 签名算法 {@link SignatureAlgorithm}* @return* @throws Exception*/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@Builderpublic 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

非对称加密 DSA算法相关推荐

  1. php封装一个加密算法,PHP封装的非对称加密RSA算法示例

    本文实例讲述了PHP封装的非对称加密RSA算法.分享给大家供大家参考,具体如下: 将php的openssl扩展中的非对称加密函数封装成一个Rsa类. 需要注意的是,在windows上,需要打开open ...

  2. 【工具编写】python实现非对称加密RSA算法

    python实现非对称加密RSA算法 0x01 RSA算法介绍 RSA加密算法是一种非对称加密算法.在公开密钥加密和电子商业中RSA被广泛使用.RSA是1977年由罗纳德·李维斯特(Ron Rives ...

  3. 非对称加密RSA算法原理及实际应用场景

    非对称加密RSA算法原理及实际应用场景 引言 应用场景 RSA 算法原理 数学基础 质数 欧拉定理 模指数运算 小白理解 为什么需要足够大的质数 引言 我数学差的离谱,所以我朋友去学AI,我还在这搞这 ...

  4. c语言字符串非对称加密,RSA算法C语言实现(支持任意位密钥)

    之前分享过三种常用MD5.SHA2和AES加密算法(点这里)实现源码,前三者分别属于哈希加密和对称加密,而另一种很常用的非对称加密RSA算法实现这次分享出来.RSA算法的原理和用途大家可以网上自行搜索 ...

  5. Java代码实现非对称加密RSA算法示例

    非对称加密:有两把密钥:使用公钥加密,必须使用私钥解密:或者使用私钥加密,必须使用公钥解密 加解密核心类:Cipher 下面代码是使用RSA算法加解密的一个示例,实现过程包括:生成密钥对,把公钥和私钥 ...

  6. 加密基础知识二 非对称加密RSA算法和对称加密

    一.RSA的计算过程 上述过程中,出现了公钥(3233,17)和私钥(3233,2753),这两组数字是怎么找出来的呢?参考RSA算法原理(二) 首字母缩写说明:E是加密(Encryption)D是解 ...

  7. 非对称加密 ECC算法

    ECC 算法 椭圆曲线密码学(Elliptic Curve Cryptography,缩写:ECC)是一种基于椭圆曲线数学的公开密钥加密算法. ECC的主要优势是它相比RSA加密算法使用较小的密钥长度 ...

  8. RSA非对称加密核心算法

    1.使用工具生成私有和公有秘钥 私有秘钥: -----BEGIN PRIVATE KEY----- MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAK ...

  9. 非对称加密——RSA算法JAVA代码实践

    文章目录 说明 RSA加解密 测试代码 打印输出 说明 1:下面代码参考自<JAVA加密解密的艺术>,有部分修改,详见原理见原书 2:下面代码是RSA在JAVA中API级别的代码实现,具体 ...

最新文章

  1. json对象转为url参数_Day48_Ajaxamp;Json
  2. Python设计模式-观察者模式
  3. 摆地摊创业赚钱完全详细攻略
  4. 一步一步SharePoint 2007系列文章目录
  5. 我的微型计算机,我的OC(超频)18年追忆!
  6. Python Django 可变参数*与**的区别
  7. 模板方法在Spring事务中的应用
  8. 【动态代理】从源码实现角度剖析JDK动态代理
  9. 洛谷P1082 同余方程 数论
  10. 3d000: no database selected_No.[C9]020
  11. 【刷题】BZOJ 3653 谈笑风生
  12. 发光二极管pcb封装图画法_【AD封装】PH2.0座子插件贴片(带3D)
  13. 大神演示win10系统语音识别应用的详细教程
  14. php监测tomcat,java_JAVA实现监测tomcat是否宕机及控制重启的方法,本文实例讲述了JAVA实现监测tom - phpStudy...
  15. EH使用IPMI基础操作
  16. pandas map applymap apply方法详解
  17. 读书笔记:数学分析新讲第一册
  18. 阿里天池大数据竞赛——口碑商家客流量预测 A
  19. 考研英语 - advanced
  20. matlab 中阿拉伯字母,常用阿拉伯字母念法

热门文章

  1. Kotlin 旅途篇(一)
  2. python时分秒_python时间时分秒与秒数的互相转换
  3. 手把手教你搭建深度学习环境
  4. suma服务器 硬盘安装,[Server] HP DL380 G6更新esxi6.0 SATA 硬盘掉线问题
  5. 【干货】营销拓客思维导图24式.pdf(附下载链接)
  6. QQ跳转浏览器php代码,网址在手机QQ内被点击时自动打开默认浏览器跳转php源码...
  7. 深入理解编译注解(三)依赖关系 apt/annotationProcessor与Provided的区别
  8. node child_process模块学习笔记
  9. Java绘图,图像处理
  10. 【bzoj3698】【XWW的难题】【有上下界的网络流】