本帖最后由 袁敏婷 于 2022-5-31 17:06 编辑
RSA数字签名
一、原理:
当A想要给B发送数据,并想进行数字签名的时候,A只需要利用自己的私钥,对数据进行数字签名算法,就可以得到一个新的签名数据,这时A需要把自己原来的数据,以及新得到的签名数据都发送给B,B接受到签名数据之后,用A的公钥对签名数据进行验证算法,看得出来的数据与A发送过来的数据是不是完全一样的即可。
二、签名过程:
1.A计算消息m的消息摘要,记为 r(m);
2.A使用私钥(n,d)对r(m)加密,生成签名s ,s满足:s=(h(m))^d mod n;
3.A发送消息和签名(m,s)给B。
三、验签过程:
1.B计算消息m的消息摘要,记为r(m); 2.B使用A的公钥(n,e)解密s,得到:R(m)=s^e mod n; 3.B比较R(m)与r(m),相同则验证为正确。
四、签名过程:
1.A提取消息m的消息摘要r(m),并使用自己的私钥对摘要r(m)进行加密,生成签名s; 2.A将签名s和消息m一起,使用B的公钥进行加密,生成密文c,发送给B。
五、验证过程:
1.B接收到密文c,使用自己的私钥解密c得到明文m和数字签名s; 2.B使用A的公钥解密数字签名s解密得到R(m); 3.B使用相同的方法提取消息m的消息摘要r(m); 4.B比较两个消息摘要。相同则验证成功,否则验证失败。
六、源代码:
- package rsaqm;
- 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;
- public class qianming {
- private static String src = "CYK";
- public static void main(String[] args) {
- jdkRSA();
- }
- public static void jdkRSA() {
- try {
- KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");// 初始化秘钥
- keyPairGenerator.initialize(512);
- KeyPair keyPair = keyPairGenerator.generateKeyPair();
- RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();// 用作验证 公钥
- RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();// 用作签名 私钥
- 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(src.getBytes());
- byte[] result = signature.sign();
- System.out.println("RSA签名是:" + result);
- X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());// 验证签名
- keyFactory = KeyFactory.getInstance("RSA");
- PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
- signature = Signature.getInstance("MD5withRSA");
- signature.initVerify(publicKey);
- signature.update(src.getBytes());
- boolean bool = signature.verify(result);
- System.out.println("签名验证结果为:" + bool);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
复制代码
七、运行结果:
|