JAVA_RSA_的加解密

Wesley13
• 阅读 743

RSA为非对称加密算法。

数字签名的过程:1、对明文数据进行HASH加密,不可逆;2、对加密后的数据再用RSA的私钥进行二次加密。

数字签名的验证过程:1、对明文数据进行HASH加密,不可逆;2、用RSA的公钥对数字签名后的数据进行解密;3、把1的结果和2的结果进行比较是否相等。

RSA加密的过程和解密的过程都需要三步:加/解密、分组、填充。这三部分每一步都可以选择各自的算法。例如:RSA/ECB/PKCS1Padding。

在这里RSA的公钥是用X509编码的。

在这里RSA的私钥使用PKCS8编码的。

 RAS算法数字签名漫画详解

import java.security.Key;
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.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;

public class Secret {

    public static final String KEY_ALGORITHM = "RSA";
    public static final String SIGNATURE_ALGORITHM = "SHA256withRSA";
    private static final String PUBLIC_KEY = "PublicKey";
    private static final String PRIVATE_KEY = "PrivateKey";
 
    public static void main(String[] args) throws Exception{
        // TODO Auto-generated method stub
        Map<String,Key> keyMap = initKeyPair();
        String publicKey = encryptBASE64(keyMap.get(PUBLIC_KEY).getEncoded());
        String privateKey = encryptBASE64(keyMap.get(PRIVATE_KEY).getEncoded());
        String data = "123456";
        byte[] miwen = encryptByPrivateKey(data.getBytes(), privateKey);
        byte[] mingwen = decryptByPublicKey(miwen, publicKey);
        String redata = new String(mingwen);
        System.out.println(redata);
        String data2 = "asdfgh";
        byte[] miwen2 = encryptByPublicKey(data2.getBytes(), publicKey);
        byte[] mingwen2 = decryptByPrivateKey(miwen2, privateKey);
        String redata2 = new String(mingwen2);
        System.out.println(redata2);
        String data3 = "678901";
        byte[] miwen3 = sign(data3.getBytes(), privateKey);
        boolean flag = verify(data3.getBytes(), publicKey, miwen3);
        System.out.println(flag);
        

    }
    //生成密匙对
    public    static Map<String,Key> initKeyPair() throws Exception{
        KeyPairGenerator kpg = KeyPairGenerator.getInstance(KEY_ALGORITHM); 
        kpg.initialize(1024);
        KeyPair keyPair = kpg.generateKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();
        Map<String,Key> keyMap = new HashMap<>();
        keyMap.put(PUBLIC_KEY, publicKey);
        keyMap.put(PRIVATE_KEY, privateKey);
        return keyMap;
    }
    //字节数组到公钥
    public static PrivateKey strToPrivateKey(String str) throws Exception{
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(decryptBASE64(str));
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
        return privateKey;
    }
    //字节数组到私钥
    public static PublicKey strToPublicKey(String str) throws Exception{
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(decryptBASE64(str));
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
        return publicKey;
    }
    //字节数组到文件字符串
    public static String encryptBASE64(byte[] bytes) {
        return Base64.getEncoder().encodeToString(bytes);
    }
    //文件字符串到字节数组
    public static byte[] decryptBASE64(String str) {
        return Base64.getDecoder().decode(str);
    }
    //用公钥加密
    public static byte[] encryptByPublicKey(byte[] data, String key) throws Exception{
        PublicKey publicKey = strToPublicKey(key);
        Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
        //Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        //加解密算法/分組算法/填充算法
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return cipher.doFinal(data);
    }
    //用私钥加密
    public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception{
        PrivateKey privateKey = strToPrivateKey(key);
        Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
        //Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        //加解密算法/分組算法/填充算法
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
        return cipher.doFinal(data);
    }
    //用公钥解密
    public static byte[] decryptByPublicKey(byte[] data, String key) throws Exception {
        PublicKey publicKey = strToPublicKey(key);
        Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
        //Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        //加解密算法/分組算法/填充算法
        cipher.init(Cipher.DECRYPT_MODE, publicKey);
        return cipher.doFinal(data);
    }
    //用私钥解密
    public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception {
        PrivateKey privateKey = strToPrivateKey(key);
        Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
        //Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        //加解密算法/分組算法/填充算法
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return cipher.doFinal(data);
    }
    //对字符串进行数字签名
    public static byte[] sign(byte[] data, String privateKey) throws Exception {
        PrivateKey priKey = strToPrivateKey(privateKey);
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initSign(priKey);
        signature.update(data);
        return signature.sign();
    }
    //对数字签名进行验证
    public static boolean verify(byte[] data, String publicKey, byte[] sign) throws Exception {
        PublicKey pubKey = strToPublicKey(publicKey);
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initVerify(pubKey);
        signature.update(data);
        return signature.verify(sign);
    }
}
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
前端尾随者 前端尾随者
2年前
sourceTree 添加 ssh key 方法
1.使用git客户的生成公私钥:id\rsa、id\rsa.pub1.1设置Git的username和email:$gitconfigglobaluser.name"xxx"$gitconfig\globaluser.email"xxx.mail@xxx.com"1.2.生成SSH密钥过程:1.2.1.检查是不是已经存在密钥(
浅谈加密算法 aes
一、目标搞了这么多期签名和加密解密,今天我们聊聊高大上的东西:加密算法。加密算法我们整体可以分为:不可逆加密算法和可逆加密算法。不可逆加密算法常见的不可逆加密算法有MD5,HMAC,SHA1、SHA224、SHA256、SHA384,和SHA512。他们的特点是,不能从加密后的结果解密出原文,主要用于校检数据的一致性,防止篡改数据,我们之前分析的大部分s
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
RSA加密、解密、签名、验签的原理及方法
一、RSA加密简介  RSA加密是一种非对称加密。可以在不直接传递密钥的情况下,完成解密。这能够确保信息的安全性,避免了直接传递密钥所造成的被破解的风险。是由一对密钥来进行加解密的过程,分别称为公钥和私钥。两者之间有数学相关,该加密算法的原理就是对一极大整数做因数分解的困难性来保证安全性。通常个人保存私钥,公钥是公开的(可能同时多人持有)。
Wesley13 Wesley13
3年前
RSA —— 典型非对称加密算法
RSA——JAVA代码(toc_0)RSA——加密过程图解(toc_1)(图1)构建RSA算法密匙对(toc_2)(图2)甲方向乙方发送RSA加密数据(toc_3)(图3)乙方向甲方发送RSA加密数据(toc_4)RSA——简述(
Stella981 Stella981
3年前
OpenSSL和Python实现RSA Key公钥加密私钥解密
基于非对称算法的RSAKey主要有两个用途,数字签名和验证(私钥签名,公钥验证),以及非对称加解密(公钥加密,私钥解密)。本文提供一个基于OpenSSL和Python进行非对称加解密的例子。1\.OpenSSL实现非对称加解密1.1生成私钥,并导出公钥生成2048bit的PEM格式的RSAKey:Key.pem$openssl
Stella981 Stella981
3年前
RSA 加密 解密 (长字符串) JAVA JS版本加解密
系统与系统的数据交互中,有些敏感数据是不能直接明文传输的,所以在发送数据之前要进行加密,在接收到数据时进行解密处理;然而由于系统与系统之间的开发语言不同。本次需求是生成二维码是通过java生成,由php来解密。基于这类需求所以选择了RSA进行加解密。生成RSA公私钥分成三步生成,第1、2步可以满足php的使用,由于java的私钥要转化为PKCS8格式
Stella981 Stella981
3年前
Openssl生成RSA公私钥以及将公钥转换成C#支持的格式
Openssl生成RSA公私钥以及将公钥转换成C支持的格式1.RSA算法介绍RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密。RSA的算法涉及三个参数,n、e、d。其中,n是两个大质数p、q的积,n被称为模数,n的二进
Wesley13 Wesley13
3年前
Java 进行 RSA 加解密时不得不考虑到的那些事儿
Java进行RSA加解密时不得不考虑到的那些事儿博客分类:java1\.加密的系统不要具备解密的功能,否则RSA可能不太合适公钥加密,私钥解密。加密的系统和解密的系统分开部署,加密的系统不应该同时具备解密的功能,这样即使黑客攻破了加密系统,他拿到的也只是一堆无法破解的密