java 弱签名算法,Java 数字签名算法

数字签名算法可以看成是带秘钥的消息摘要算法,用于验证数据完整性、认证数据来源,并起到抗否认的作用。遵循私钥加签,公钥验签的规则,数字签名算法是非对称加密算法和消息摘要算法的结合体。数字签名算法主要包括RSA和DSA。这节记录下这两种算法在JDK8下的实现。

数字签名加签验签流程分为以下几步:A在本地构建秘钥对,并将公钥发布给B;

A使用私钥对数据进行签名;

A发送签名和数据给B;

B使用公钥对签名和数据进行验签。

RSA

RSA数字签名算法主要分为MD系列和SHA系列两大类。MD系列主要包括MD2withRSA和MD5withRSA共2种数字签名算法;SHA系列主要包括SHA1withRSA、SHA224withRSA、SHA256withRSA、SHA384withRSA和SHA512withRSA共5种数字签名算法。

代码示例:1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44import org.junit.Test;

import java.security.*;

import java.util.Base64;

public class RsaSignatureDemo{

@Test

public void test() throws Exception{

String value = "mrbird's blog";

// 非对称加密算法

String algorithm = "RSA";

// 签名算法,RSA+SHA

String signAlgorithm = "SHA256withRSA";

// ----- 公私钥生成 --------

// 实例化秘钥对生成器

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);

// 初始化,秘钥长度512~16384位,64倍数

keyPairGenerator.initialize(512);

// 生成秘钥对

KeyPair keyPair = keyPairGenerator.generateKeyPair();

// 公钥

PublicKey publicKey = keyPair.getPublic();

System.out.println("RSA公钥: " + Base64.getEncoder().encodeToString(publicKey.getEncoded()));

// 私钥

PrivateKey privateKey = keyPair.getPrivate();

System.out.println("RSA私钥: " + Base64.getEncoder().encodeToString(privateKey.getEncoded()));

// ----- 私钥加签 ---------

// 获取签名对象

Signature signature = Signature.getInstance(signAlgorithm);

signature.initSign(privateKey);

signature.update(value.getBytes());

byte[] sign = signature.sign();

System.out.println("签名值: " + Base64.getEncoder().encodeToString(sign));

// ----- 公钥验签 ---------

signature.initVerify(publicKey);

signature.update(value.getBytes());

System.out.println("验签结果: " + signature.verify(sign));

}

}

秘钥对生成过程和上篇RSA介绍的无异,主要关注加签和验签操作即可,程序输出如下:1

2

3

4RSA公钥: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKTTlw+zyhGzmTmhT5w9vEP1ejOcVfM2rHbz8jUae7InAh42R9ZaYUk1c3q0uqmTv8xKOnszU/vrdV52zoFM+OMCAwEAAQ==

RSA私钥: MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEApNOXD7PKEbOZOaFPnD28Q/V6M5xV8zasdvPyNRp7sicCHjZH1lphSTVzerS6qZO/zEo6ezNT++t1XnbOgUz44wIDAQABAkBsZQXz+p2J1J2Qq8fqDSNxYc8Sf956SttSgw0m5Rqxxiw10cgHt67uocu3qK6UeMuJuaOiN3YT48kvFp6Joc75AiEA4L7R1zDWcOdWf2BE/k3yxJ4Uv0vbIZ9vWLuJGBR3xK0CIQC7v5f2fcedBWbJ/kR7CvbFE91ivM55dvWZMe/JrjXVzwIgFUn+FqRJq+g+CVLVNkGr/XP8AyLsXwL7SSx6kA1gSwECIHysAn4VEftr/dC+Pr0yD6HYyhbp53XzD6214lQbkfYzAiB1b2wNi0Y3N+D/OIrGUHlwgA0vkX82NP3V8qMDmRbCTQ==

签名值: HVN5WkhND0hy/xY43h8r3+AVt6oxMSv1Ug/Y+bv1tGxw4ePQtIgzFwK0lQQbhIlwts2d2STwQBews4dXCfEMmA==

验签结果: true

需要注意的是不同签名算法需要的秘钥长度最小值不同,大伙可以自己试试。

DSA

DSA算法与RSA算法都是数字证书中不可或缺的两种算法。两者不同的是,DSA算法仅包含数字签名算法,使用DSA算法的数字证书无法进行加密通信,而RSA算法既包含加密/解密算法,同时兼有数字签名算法。

JDK8支持SHA1withDSA、SHA224withDSA、SHA256withDSA、SHA384withDSA和SHA512withDSA这五种DSA数字签名算法。

代码示例(只需将上面的例子算法替换下就好,并且注意秘钥的长度范围):1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44import org.junit.Test;

import java.security.*;

import java.util.Base64;

public class RsaSignatureDemo{

@Test

public void test() throws Exception{

String value = "mrbird's blog";

// 非对称加密算法

String algorithm = "DSA";

// 签名算法,DSA+SHA

String signAlgorithm = "SHA224withDSA";

// ----- 公私钥生成 --------

// 实例化秘钥对生成器

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);

// 初始化,秘钥长度512~1024位,64倍数

keyPairGenerator.initialize(1024);

// 生成秘钥对

KeyPair keyPair = keyPairGenerator.generateKeyPair();

// 公钥

PublicKey publicKey = keyPair.getPublic();

System.out.println("DSA公钥: " + Base64.getEncoder().encodeToString(publicKey.getEncoded()));

// 私钥

PrivateKey privateKey = keyPair.getPrivate();

System.out.println("DSA私钥: " + Base64.getEncoder().encodeToString(privateKey.getEncoded()));

// ----- 私钥加签 ---------

// 获取签名对象

Signature signature = Signature.getInstance(signAlgorithm);

signature.initSign(privateKey);

signature.update(value.getBytes());

byte[] sign = signature.sign();

System.out.println("签名值: " + Base64.getEncoder().encodeToString(sign));

// ----- 公钥验签 ---------

signature.initVerify(publicKey);

signature.update(value.getBytes());

System.out.println("验签结果: " + signature.verify(sign));

}

}

运行结果如下:1

2

3

4DSA公钥: MIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGAcW0aiebAWi5M18Lu6QS/1OoHbtw2I7kyivwExbNAZpWR9I9sNIwE1T0a491t1oqRV1cdBHyd9jiJqFwfLG6k5QidasXTgGYSsSZqFBebP5nrF5q3RtkosoHeHVKDnShQf5b36NK53CpCRfLayk2e5inu7CCCo+a58piAMiF3c+k=

DSA私钥: MIIBTAIBADCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoEFwIVAIv03r5wR+DolDC5bGFOqQ2vuHlo

签名值: MCwCFBRba/HI5/tLt+exzpgvLoq5mAwaAhQvaVv4dbGFNtMpcI4ZeqjgAGeGyg==

验签结果: true

1、数字签名原理 用RSA算法数字签名,总的来说,就是签名者用私钥参数d加密,也就是签名;验证者用签字者的公钥参数e解密来完成认证。 下面简要描述数字签名和认证的过程。 (1)、生成密钥 为用户随机生成一对密钥:公钥(e,n)和私钥(d,n). (2)、签名过程 a) 计算消息的散列值H(M). b) 用私钥(d,n)加密散列值:s=(H(M)) mod n,签名结果就是s. c) 发送消息和签名(M,s). (3)、认证过程 a) 取得发送方的公钥(e,n). b) 解密签名s:h=s mod n. c) 计算消息的散列值H(M). d) 比较,如果h=H(M),表示签名有效;否则,签名无效。 根据上面的过程,我们可以得到RSA数字签名的框图如图2-1: 图 2-1 RSA数字签名框图 2、 假设Alice想和Bob通信,以本地两个文件夹Alice和Bob模拟两个用户,实现消息M和签名的模拟分发 (1)、Alice通过RSA算法生成一对密钥:公钥(e,n)和私钥(d,n),将公私钥分别存入pubKey.txt和priKey.txt中。 pubKey.txt中公钥如下: priKey.txt中私钥如下: (2)、将Alice中的pubKey.txt拷到Bob中,模拟公玥的分发。 (3)、将Alice中的消息info.txt做散列,将散列后的值存入hashInfo.txt中。 (4)、将Alice中的消息hashInfo.txt和签名sign.txt拷到Bob中,实现M密文状态下的签名与模拟分发、消息传递。 (5)Bob取得公钥pubKey.txt,用公钥解密签名,计算消息的散列值H(M).比较,如果h=H(M),表示签名有效;否则,签名无效。 后台运行结果如下:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值