数据安全管理:RSA加密算法,签名验签流程详解-阿里云开发者社区

开发者社区> 知了一笑> 正文

数据安全管理:RSA加密算法,签名验签流程详解

简介: 本文源码:GitHub·点这里 || GitEE·点这里 一、RSA算法简介 1、加密解密 RSA加密是一种非对称加密,在公开密钥加密和电子商业中RSA被广泛使用。可以在不直接传递密钥的情况下,完成加解密操作。
+关注继续查看

本文源码:GitHub·点这里 || GitEE·点这里

一、RSA算法简介

1、加密解密

RSA加密是一种非对称加密,在公开密钥加密和电子商业中RSA被广泛使用。可以在不直接传递密钥的情况下,完成加解密操作。这能够确保信息的安全性,避免了直接传递密钥所造成的被破解的风险。是由一对密钥来进行加解密的过程,分别称为公钥和私钥。该加密算法的原理就是对一极大整数做因数分解的困难性来保证安全性。

2、签名验签

数字签名就是信息的来源添加一段无法被伪造的加密字符串,这段数字串作为对信息的来源真实性的一个有效证明。这个过程称为签名和验签。

二、场景描述

  • 消息发送方:甲方,持有公钥
  • 消息接收方:乙方,持有私钥

1、加密解密过程

(1)、乙方生成一对密钥即公钥和私钥,私钥不公开,乙方自己持有,公钥为公开,甲方持有。

(2)、乙方收到甲方加密的消息,使用私钥对消息进行解密,获取明文。

2、签名验签过程

(1)、乙方收到消息后,需要回复甲方,用私钥对回复消息签名,并将消息明文和消息签名回复甲方。

(2)、甲方收到消息后,使用公钥进行验签,如果验签结果是正确的,则证明消息是乙方回复的。

三、源代码实现

1、密钥字符串获取

  • 代码生成
private static HashMap<String, String> getTheKeys() {
    HashMap<String, String> keyPairMap = new HashMap<String, String>();
    KeyPairGenerator keyPairGen = null;
    try {
        keyPairGen = KeyPairGenerator.getInstance("RSA");
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    // 密钥大小:1024 位
    keyPairGen.initialize(1024);
    KeyPair keyPair = keyPairGen.generateKeyPair();
    String publicKey = printBase64Binary(keyPair.getPublic().getEncoded());
    String privateKey = printBase64Binary(keyPair.getPrivate().getEncoded());
    keyPairMap.put("publicKey", publicKey);
    keyPairMap.put("privateKey", privateKey);
    return keyPairMap ;
}
  • 读取文件

01_1

文件位置

public static final String PUB_KEY = "rsaKey/public.key" ;
public static final String PRI_KEY = "rsaKey/private.key" ;

文件加载

public static String getKey (String keyPlace) throws Exception {
    BufferedReader br= null;
    try {
        br= new BufferedReader(new InputStreamReader(RsaCryptUtil.class.getClassLoader().
                                                     getResourceAsStream(keyPlace)));
        String readLine= null;
        StringBuilder keyValue = new StringBuilder();
        while((readLine= br.readLine())!=null){
            if(!(readLine.charAt(0)=='-')){
                keyValue.append(readLine);
            }
        }
        return keyValue.toString();
    } catch (Exception e) {
        throw new Exception("RSA密钥读取错误",e) ;
    } finally{
        if (br != null) {
            try {
                br.close();
            } catch (Exception e) {
                System.out.println("密钥读取流关闭异常");
            }
        }
    }
}

2、公钥和私钥

  • 公钥字符串生成公钥
public static RSAPublicKey createPublicKey(String publicKeyValue) throws Exception {
    try {
        byte[] buffer = DatatypeConverter.parseBase64Binary(publicKeyValue);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
        return (RSAPublicKey) keyFactory.generatePublic(keySpec);
    } catch (Exception e) {
        throw new Exception("公钥创建失败", e);
    }
}
  • 私钥字符串生成私钥
public static RSAPrivateKey createPrivateKey(String privateKeyValue) throws Exception {
    try {
        byte[] buffer = javax.xml.bind.DatatypeConverter.parseBase64Binary(privateKeyValue);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
    } catch (Exception e) {
        throw new Exception("私钥创建失败", e);
    }
}

3、加密和解密

  • 公钥加密
public static String encrypt(RSAPublicKey publicKey, byte[] clearData) throws Exception {
    if (publicKey == null) {
        throw new Exception("加密公钥为空, 无法加密");
    }
    try {
        Cipher cipher = Cipher.getInstance("RSA") ;
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] output = cipher.doFinal(clearData);
        return printBase64Binary(output);
    } catch (Exception e) {
        throw new Exception("公钥加密失败",e);
    }
}
  • 私钥解密
public static String decrypt(RSAPrivateKey privateKey, byte[] cipherData) throws Exception {
    if (privateKey == null) {
        throw new Exception("解密私钥为空, 无法解密");
    }
    try {
        Cipher cipher = Cipher.getInstance("RSA") ;
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] output = cipher.doFinal(cipherData);
        return new String(output);
    } catch (BadPaddingException e) {
        throw new Exception("私钥解密失败",e);
    }
}

4、签名和验签

  • 私钥签名
public static String sign (String signData, PrivateKey privateKey) throws Exception {
    byte[] keyBytes = privateKey.getEncoded();
    PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    PrivateKey key = keyFactory.generatePrivate(keySpec);
    Signature signature = Signature.getInstance("MD5withRSA");
    signature.initSign(key);
    signature.update(signData.getBytes());
    return printBase64Binary(signature.sign());
}
  • 公钥验签
public static boolean verify(String srcData, PublicKey publicKey, String sign) throws Exception {
    byte[] keyBytes = publicKey.getEncoded();
    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    PublicKey key = keyFactory.generatePublic(keySpec);
    Signature signature = Signature.getInstance("MD5withRSA");
    signature.initVerify(key);
    signature.update(srcData.getBytes());
    return signature.verify(parseBase64Binary(sign));
}

5、编码和解码

/**
 * 字节数组转字符
 */
public static String printBase64Binary(byte[] bytes) {
    return DatatypeConverter.printBase64Binary(bytes);
}
/**
 * 字符转字节数组
 */
public static byte[] parseBase64Binary(String value) {
    return DatatypeConverter.parseBase64Binary(value);
}

6、测试代码块

  • 密钥生成测试
public static void testCreateKey () throws Exception {
    HashMap<String, String> map = RsaCryptUtil.getTheKeys();
    String privateKeyStr=map.get("privateKey");
    String publicKeyStr=map.get("publicKey");
    System.out.println("私钥:"+privateKeyStr);
    System.out.println("公钥:"+publicKeyStr);
    //消息发送方
    String originData="cicada-smile";
    System.out.println("原文:"+originData);
    String encryptData = RsaCryptUtil.encrypt(RsaCryptUtil.createPublicKey(publicKeyStr),
                                              originData.getBytes());
    System.out.println("加密:"+encryptData);
    //消息接收方
    String decryptData=RsaCryptUtil.decrypt(RsaCryptUtil.createPrivateKey(privateKeyStr),
                                            RsaCryptUtil.parseBase64Binary(encryptData));
    System.out.println("解密:"+decryptData);
}
  • 密钥读取测试
public static void testReadKey () throws Exception {
    String value = getKey("rsaKey/public.key");
    System.out.println(value);
    String privateKeyStr = getKey(RsaCryptUtil.PRI_KEY) ;
    String publicKeyStr = getKey(RsaCryptUtil.PUB_KEY) ;
    //消息发送方
    String originData="cicada-smile";
    System.out.println("原文:"+originData);
    String encryptData = RsaCryptUtil.encrypt(RsaCryptUtil.createPublicKey(publicKeyStr),
                                              originData.getBytes());
    System.out.println("加密:"+encryptData);
    //消息接收方
    String decryptData=RsaCryptUtil.decrypt(RsaCryptUtil.createPrivateKey(privateKeyStr),
                                            RsaCryptUtil.parseBase64Binary(encryptData));
    System.out.println("解密:"+decryptData);
}
  • 签名验签测试
public static void testSignVerify () throws Exception {
    String signData = "cicada-smile" ;
    String privateKeyStr = getKey(RsaCryptUtil.PRI_KEY) ;
    String publicKeyStr = getKey(RsaCryptUtil.PUB_KEY) ;
    String signValue = sign(signData,RsaCryptUtil.createPrivateKey(privateKeyStr)) ;
    boolean flag = verify(signData,RsaCryptUtil.createPublicKey(publicKeyStr),signValue);
    System.out.println("原文:"+signData);
    System.out.println("签名:"+signValue);
    System.out.println("验签:"+flag);
}

四、源代码地址

GitHub·地址
https://github.com/cicadasmile
GitEE·地址
https://gitee.com/cicadasmile

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
RSA公钥加密—私钥解密&amp;私钥加密—公钥解密&amp;私钥签名—公钥验证签名
关于RSA算法,前面有介绍,点击打开链接。 这里直接有实现。 代码太多就不直接贴了,免积分下载。 http://download.csdn.net/detail/acmjk/7310847
1114 0
【云计算的1024种玩法】安装 MariaDB 并通过 DMS 管理
之前有提到过阿里云的数据管理,也就是阿里云的RDS管理工具。由于自己比较喜欢带 GUI 的管理工具,所以之前一直使用 phpMyAdmin,不过呢,要是不使用 PHP 环境,像安装一个 Ghost 博客就完全用不到 PHP 环境,这时候就很尴尬了。这时候我就想起了 DMS。
2995 0
RSACryptoServiceProvider加密解密签名验签和DESCryptoServiceProvider加解密
原文:RSACryptoServiceProvider加密解密签名验签和DESCryptoServiceProvider加解密 C#在using System.Security.Cryptography下有 DESCryptoServiceProvider RSACryptoServiceProvider  DESCryptoServiceProvider 是用于对称加密 RSACryptoServiceProvider是用于非对称加密  对称加密的意思:有一个密钥 相当于加密算法,加密用它来加密,解密也需要用到它。
771 0
Silverlight中非对称加密及数字签名RSA算法的实现
RSA算法是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。它的安全性是基于大整数素因子分解的困难性,而大整数因子分解问题是数学上的著名难题,至今没有有效的方法予以解决,因此可以确保RSA算法的安全性。
669 0
[安全]-应急响应的基本流程
应急响应的基本流程: 1.了解情况 2. 遏制传播风险 3.已知高危漏洞排查 4.系统基本信息 5.异常连接排查 6.正在运行的异常进程排查 7.异常账号排查 8.异常文件分析 9.启动项排查 10.计划任务排查(定时任务) 11.日志排查 12.恢复阶段 13.跟踪总结
114 0
RSA和RSA2签名算法区别
RSA和RSA2签名算法 什么是数字签名? 一个很好的说明文档可以参考:What is a Digital Signature?,中文翻译可以参考:数字签名是什么?. 简单来说,签名主要包含两个过程:摘要和非对称加密,首先对需要签名的数据做摘要(类似于常见的MD5)后得到摘要结果,然后通过签名者的私钥对摘要结果进行非对称加密即可得到签名结果。
1822 0
+关注
知了一笑
公众号:知了一笑
198
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载