数字签名– RSA、DSA、ECDSA

1、 什么是数字签名

数字签名,就是只有信息发送者才能产生的别人无法伪造的一段数字串,这段数字串同时也是对信息发送者发送信息真实性的一个有效证明。

数字签名是带有密钥的消息摘要算法

2、 数字签名的功能

保证信息传输的完整性、发送者的身份认证、防止交易中的抵赖发生。

首先由发送方构建密钥对,公布密钥对(仅发送方和接收方可知);发送方使用私钥根据摘要生成数字签名,将数字签名和数据报文一起发送给接收方;接收方使用公布的公钥对数字签名验证,验证通过则说明数据传输中没有被修改过,可正常接收,否则说明数据被修改过,可拒绝接收报文信息。

3、 数字签名测试代码

RSA、DSA、ECDSA 的代码编写近乎相同;全部粘贴出来,可以直接运行测试。

1)RSA CODE

?

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

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

import java.security.KeyFactory;

import java.security.KeyPair;

import java.security.KeyPairGenerator;

import java.security.PrivateKey;

import java.security.PublicKey;

import java.security.Signature;

import java.security.interfaces.RSAPrivateKey;

import java.security.interfaces.RSAPublicKey;

import java.security.spec.PKCS8EncodedKeySpec;

import java.security.spec.X509EncodedKeySpec;

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

public class test {

    //摘要

    private static final String strMsg = "hold on";

     

    public static void main(String[] args) throws Exception {

        jdkRSA();

    }

     

    /**

     * RSA 使用最为广泛的数字签名算法(MD、SHA两类)

     * @throws Exception

     */

    public static void jdkRSA() throws Exception{

        //1.初始化密钥

        KeyPair keyPair = initKey();

         

        //2.执行签名(用私钥签名)

        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();

        byte[] sign = privateKeySign(strMsg, rsaPrivateKey);

        String signStr = Base64.encodeBase64String(sign); 

        System.out.println("sign String :"+signStr);//数字签名格式转换,以便报文传输用

         

        RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();

        String publicKeyStr =  Base64.encodeBase64String(rsaPublicKey.getEncoded());

        System.out.println("publicKeyStr String :"+publicKeyStr);//提供给对端,以便于对端使用公钥验证签名

         

         

        //3.验证签名(公钥验证签名)

        boolean result = publicKeyVerify(Base64.decodeBase64(signStr), Base64.decodeBase64(publicKeyStr));

        System.out.println("JDK RSA verify:"+result);

    }

     

    /**

     * 1.初始化密钥,采用RSA

     * @return

     * @throws Exception

     */

    public static KeyPair initKey() throws Exception{

        KeyPairGenerator  keyPairGenerator = KeyPairGenerator.getInstance("RSA");

        keyPairGenerator.initialize(512); //key长度设置

        KeyPair keyPair = keyPairGenerator.generateKeyPair();

         

        return keyPair;

    }

     

     

    /**

     * 2.执行签名(用私钥签名)

     * @return

     * @throws Exception

     */

    public static byte[] privateKeySign(String data,RSAPrivateKey rsaPrivateKey) throws Exception{

        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());

        KeyFactory keyFactory = KeyFactory.getInstance("RSA");

        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);

        Signature signature = Signature.getInstance("MD5withRSA");

        signature.initSign(privateKey);

        signature.update(strMsg.getBytes());

        byte[] sign = signature.sign();

         

        return sign;

    }

     

    /**

     * 3.公钥验证签名(摘要+签名串+公钥)

     * @throws Exception

     */

    public static boolean publicKeyVerify(byte[] sign,byte[] rsaPublicKey) throws Exception{

        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey);

        KeyFactory keyFactory = KeyFactory.getInstance("RSA");

        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);

        Signature signature = Signature.getInstance("MD5withRSA");

        signature.initVerify(publicKey);

        signature.update(strMsg.getBytes());

        boolean result = signature.verify(sign);

         

        return result;

    }

}

2)DSA CODE

?

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

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

import java.security.KeyFactory;

import java.security.KeyPair;

import java.security.KeyPairGenerator;

import java.security.PrivateKey;

import java.security.PublicKey;

import java.security.Signature;

import java.security.interfaces.DSAPrivateKey;

import java.security.interfaces.DSAPublicKey;

import java.security.spec.PKCS8EncodedKeySpec;

import java.security.spec.X509EncodedKeySpec;

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

public class test {

    //摘要

    private static final String strMsg = "hold on";

     

    public static void main(String[] args) throws Exception {

        jdkDSA();

    }

     

    /**

     *  DSA code的编写与RSA近乎相同

     * @throws Exception

     */

    public static void jdkDSA() throws Exception{

        //1.初始化密钥

        KeyPair keyPair = initKey();

         

        //2.执行签名(用私钥签名)

        DSAPrivateKey dsaPrivateKey = (DSAPrivateKey) keyPair.getPrivate();

        byte[] sign = privateKeySign(strMsg, dsaPrivateKey);

        String signStr = Base64.encodeBase64String(sign); 

        System.out.println("sign String :"+signStr);//数字签名格式转换,以便报文传输用

         

        DSAPublicKey dsaPublicKey = (DSAPublicKey) keyPair.getPublic();

        String publicKeyStr =  Base64.encodeBase64String(dsaPublicKey.getEncoded());

        System.out.println("publicKeyStr String :"+publicKeyStr);//提供给对端,以便于对端使用公钥验证签名

         

         

        //3.验证签名(公钥验证签名)

        boolean result = publicKeyVerify(Base64.decodeBase64(signStr), Base64.decodeBase64(publicKeyStr));

        System.out.println("JDK DSA verify:"+result);

    }

     

    /**

     * 1.初始化密钥,采用DSA

     * @return

     * @throws Exception

     */

    public static KeyPair initKey() throws Exception{

        KeyPairGenerator  keyPairGenerator = KeyPairGenerator.getInstance("DSA");

        keyPairGenerator.initialize(512); //key长度设置

        KeyPair keyPair = keyPairGenerator.generateKeyPair();

         

        return keyPair;

    }

     

     

    /**

     * 2.执行签名(用私钥签名)

     * @return

     * @throws Exception

     */

    public static byte[] privateKeySign(String data,DSAPrivateKey dsaPrivateKey) throws Exception{

        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(dsaPrivateKey.getEncoded());

        KeyFactory keyFactory = KeyFactory.getInstance("DSA");

        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);

        Signature signature = Signature.getInstance("SHA1withDSA");

        signature.initSign(privateKey);

        signature.update(strMsg.getBytes());

        byte[] sign = signature.sign();

         

        return sign;

    }

     

    /**

     * 3.公钥验证签名(摘要+签名串+公钥)

     * @throws Exception

     */

    public static boolean publicKeyVerify(byte[] sign,byte[] dsaPublicKey) throws Exception{

        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(dsaPublicKey);

        KeyFactory keyFactory = KeyFactory.getInstance("DSA");

        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);

        Signature signature = Signature.getInstance("SHA1withDSA");

        signature.initVerify(publicKey);

        signature.update(strMsg.getBytes());

        boolean result = signature.verify(sign);

         

        return result;

    }

}

3)ECDSA CODE

?

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

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

import java.security.KeyFactory;

import java.security.KeyPair;

import java.security.KeyPairGenerator;

import java.security.PrivateKey;

import java.security.PublicKey;

import java.security.Signature;

import java.security.interfaces.ECPrivateKey;

import java.security.interfaces.ECPublicKey;

import java.security.spec.PKCS8EncodedKeySpec;

import java.security.spec.X509EncodedKeySpec;

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

public class test {

    //摘要

    private static final String strMsg = "hold on";

     

    public static void main(String[] args) throws Exception {

        jdkECDSA();

    }

     

    /**

     * ECDSA 微软的椭圆曲线算法 jdk1.7以后引入的算法

     * @throws Exception

     */

    public static void jdkECDSA() throws Exception{

        //1.初始化密钥

        KeyPair keyPair = initKey();

         

        //2.执行签名(用私钥签名)

        ECPrivateKey ecPrivateKey = (ECPrivateKey) keyPair.getPrivate();

        byte[] sign = privateKeySign(strMsg,ecPrivateKey);

        String signStr = Base64.encodeBase64String(sign); 

        System.out.println("sign String :"+signStr);//数字签名格式转换,以便报文传输用

         

        ECPublicKey ecPublicKey = (ECPublicKey) keyPair.getPublic();

        String publicKeyStr =  Base64.encodeBase64String(ecPublicKey.getEncoded());

        System.out.println("publicKeyStr String :"+publicKeyStr);//提供给对端,以便于对端使用公钥验证签名

         

         

        //3.验证签名(公钥验证签名)

        boolean result = publicKeyVerify(Base64.decodeBase64(signStr), Base64.decodeBase64(publicKeyStr));

        System.out.println("JDK DSA verify:"+result);

    }

     

    /**

     * 1.初始化密钥,采用ECDSA

     * @return

     * @throws Exception

     */

    public static KeyPair initKey() throws Exception{

        KeyPairGenerator  keyPairGenerator = KeyPairGenerator.getInstance("EC");

        keyPairGenerator.initialize(256); //key长度设置

        KeyPair keyPair = keyPairGenerator.generateKeyPair();

         

        return keyPair;

    }

     

     

    /**

     * 2.执行签名(用私钥签名)

     * @return

     * @throws Exception

     */

    public static byte[] privateKeySign(String data,ECPrivateKey ecPrivateKey) throws Exception{

        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(ecPrivateKey.getEncoded());

        KeyFactory keyFactory = KeyFactory.getInstance("EC");

        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);

        Signature signature = Signature.getInstance("SHA1withECDSA");

        signature.initSign(privateKey);

        signature.update(strMsg.getBytes());

        byte[] sign = signature.sign();

         

        return sign;

    }

     

    /**

     * 3.公钥验证签名(摘要+签名串+公钥)

     * @throws Exception

     */

    public static boolean publicKeyVerify(byte[] sign,byte[] dsaPublicKey) throws Exception{

        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(dsaPublicKey);

        KeyFactory keyFactory = KeyFactory.getInstance("EC");

        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);

        Signature signature = Signature.getInstance("SHA1withECDSA");

        signature.initVerify(publicKey);

        signature.update(strMsg.getBytes());

        boolean result = signature.verify(sign);

         

        return result;

    }

}

猜你喜欢

转载自blog.csdn.net/adsadadaddadasda/article/details/81750904