加密解决方案-Java实现RSA非对称加密

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 本文基于RSA加密算法原理,详述什么是RSA算法、RSA加密解密原理进行实践的过程。

一、什么是RSA加密算法:

RSA加密算法是一种非对称加密算法,所谓非对称,就是指该算法加密和解密使用不同的密钥,即使用加密密钥进行加密、解密密钥进行解密。在RAS算法中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然解密密钥SK是由公开密钥PK决定的,由于无法计算出大数n的欧拉函数phi(N),所以不能根据PK计算出SK。

也就是说,对极大整数做因数分解的难度决定了RSA算法的可靠性。理论上,只要其钥匙的长度n足够长,用RSA加密的信息实际上是不能被解破的。

RSA算法通常是先生成一对RSA密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开。为提高保密强度,RSA密钥至少为500位长,一般推荐使用1024位(对标文章结尾补充说明)。这就使加密的计算量很大。为减少计算量,在传送信息时,常采用传统加密方法与公开密钥加密方法相结合的方式,即信息采用改进的DES或IDEA密钥加密,然后使用RSA密钥加密对话密钥和信息摘要。对方收到信息后,用不同的密钥解密并可核对信息摘要。

二、RSA加密方式

RSA加密是对明文的E次方后除以N后求余数的过程。所以,只要知道E和N任何人都可以进行RSA加密了,所以说E、N是RSA加密的密钥,也就是说E和N的组合就是公钥,我们用(E,N)来表示公钥:

密文=明文EmodN密文=明文EmodN

三、RSA解密过程

密文进行D次方后除以N的余数就是明文,这就是RSA解密过程。知道D和N就能进行解密密文了,所以D和N的组合就是私钥:

明文=密文DmodN明文=密文DmodN

四、进行实践

1、确定加密算法

// 加密算法privatefinalstaticStringALGORITHM_RSA="RSA";

2、生成公钥私钥密钥对

//生成公钥,私钥的密钥对publicstaticList<String>getRSAKeyString(intmodulus) throwsNoSuchAlgorithmException{
List<String>keyList=newArrayList<>(2);
//密钥对生成,生成规范-RSA算法KeyPairGeneratorkeyPairGen=KeyPairGenerator.getInstance(ALGORITHM_RSA);
//初始化模长keyPairGen.initialize(modulus);
//生成密钥对KeyPairkeyPair=keyPairGen.generateKeyPair();
StringpublicKey=Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded());
StringprivateKey=Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded());
keyList.add(publicKey);
keyList.add(privateKey);
returnkeyList;
}
// Java中RSAPublicKeySpec、X509EncodedKeySpec支持生成RSA公钥// 此处使用X509EncodedKeySpec生成publicstaticRSAPublicKeygetPublicKey(StringpublicKey) throwsException {
KeyFactorykeyFactory=KeyFactory.getInstance(ALGORITHM_RSA);
byte[] keyBytes=Base64.getDecoder().decode(publicKey);
X509EncodedKeySpecspec=newX509EncodedKeySpec(keyBytes);
return (RSAPublicKey) keyFactory.generatePublic(spec);
}
// Java中只有RSAPrivateKeySpec、PKCS8EncodedKeySpec支持生成RSA私钥// 此处使用PKCS8EncodedKeySpec生成publicstaticRSAPrivateKeygetPrivateKey(StringprivateKey) throwsException {
KeyFactorykeyFactory=KeyFactory.getInstance(ALGORITHM_RSA);
byte[] keyBytes=Base64.getDecoder().decode(privateKey);
PKCS8EncodedKeySpecspec=newPKCS8EncodedKeySpec(keyBytes);
return (RSAPrivateKey) keyFactory.generatePrivate(spec);
}

3、编写公钥加密步骤

//公钥加密publicstaticStringencryptByPublicKey(Stringdata, RSAPublicKeypublicKey)throwsException {
Ciphercipher=Cipher.getInstance(ALGORITHM_RSA);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
// 模长n转换成字节数intmodulusSize=publicKey.getModulus().bitLength() /8;
// PKCS Padding长度为11字节,所以实际要加密的数据不能要 - 11byteintmaxSingleSize=modulusSize-11;
// 切分字节数组,每段不大于 maxSingleSizebyte[][] dataArray=splitArray(data.getBytes(), maxSingleSize);
ByteArrayOutputStreamout=newByteArrayOutputStream();
// 分组加密,并将加密后的内容写入输出字节流for (byte[] s : dataArray) {
out.write(cipher.doFinal(s));
    }
// 使用Base64将字节数组转换String类型returnBase64.getEncoder().encodeToString(out.toByteArray());
}

4、编写私钥解密过程

//私钥解密publicstaticStringdecryptByPrivateKey(Stringdata, RSAPrivateKeyprivateKey)
throwsException {
Ciphercipher=Cipher.getInstance(ALGORITHM_RSA);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
// RSA加密算法的模长 nintmodulusSize=privateKey.getModulus().bitLength() /8;
byte[] dataBytes=data.getBytes();
// 之前加密的时候做了转码,此处需要使用Base64进行解码byte[] decodeData=Base64.getDecoder().decode(dataBytes);
// 切分字节数组,使每段不大于modulusSizebyte[][] splitArrays=splitArray(decodeData, modulusSize);
ByteArrayOutputStreamout=newByteArrayOutputStream();
for(byte[] arr : splitArrays){
out.write(cipher.doFinal(arr));
    }
returnnewString(out.toByteArray());
}

5、切分数组工具方法

//切分数组privatestaticbyte[][] splitArray(byte[] data,intlen){
intdataLen=data.length;
if (dataLen<=len) {
returnnewbyte[][]{data};
    }
byte[][] result=newbyte[(dataLen-1)/len+1][];
intresultLen=result.length;
for (inti=0; i<resultLen; i++) {
if (i==resultLen-1) {
intslen=dataLen-len*i;
byte[] single=newbyte[slen];
System.arraycopy(data, len*i, single, 0, slen);
result[i] =single;
break;
        }
byte[] single=newbyte[len];
System.arraycopy(data, len*i, single, 0, len);
result[i] =single;
    }
returnresult;
}

6、主方法

publicstaticvoidmain(String[] args) throwsException {
Stringmessage="红色基因是一种革命精神的传承,鼓舞着一代又一代中华儿女为了实现中华民族的伟大复兴的中国梦而坚强自立、坚持梦想、勇往直前!";
// 使用字符串生成公钥、私钥完成加解密List<String>keyStringList=AsyEnc.getRSAKeyString(1024);
StringpukString=keyStringList.get(0);
StringprkString=keyStringList.get(1);
System.out.println("公钥:"+pukString);
System.out.println("私钥:"+prkString);
// 生成公钥RSAPublicKeypuk=AsyEnc.getPublicKey(pukString);
// 生成私钥RSAPrivateKeyprk=AsyEnc.getPrivateKey(prkString);
// 加密messageStringencryptedMsg=AsyEnc.encryptByPublicKey(message, puk);
StringdecryptedMsg=AsyEnc.decryptByPrivateKey(encryptedMsg, prk);
System.out.println("加密后 message : "+encryptedMsg);
System.out.println("解密后 message : "+decryptedMsg);
}

7、测试执行

image.png

8、补充说明

主方法中 :getRSAKeyString(1024)为自设定mod值,也为下图中RAS密钥长度

           image.png

目录
相关文章
|
3月前
|
安全 算法 网络安全
浅谈非对称加密(RSA)
浅谈非对称加密(RSA)
170 0
|
1月前
|
数据库 数据安全/隐私保护 Windows
Windows远程桌面出现CredSSP加密数据修正问题解决方案
【10月更文挑战第30天】本文介绍了两种解决Windows系统凭据分配问题的方法。方案一是通过组策略编辑器(gpedit.msc)启用“加密数据库修正”并将其保护级别设为“易受攻击”。方案二是通过注册表编辑器(regedit)在指定路径下创建或修改名为“AllowEncryptionOracle”的DWORD值,并将其数值设为2。
503 3
|
2月前
|
Java Maven 数据安全/隐私保护
如何实现Java打包程序的加密代码混淆,避免被反编译?
【10月更文挑战第15天】如何实现Java打包程序的加密代码混淆,避免被反编译?
242 2
|
2月前
|
算法 安全 Go
RSA加密算法详解与Python和Go实现
RSA加密算法详解与Python和Go实现
178 1
|
2月前
|
算法 安全 网络安全
使用 Python 实现 RSA 加密
使用 Python 实现 RSA 加密
111 2
|
2月前
|
安全 算法 Java
数据库信息/密码加盐加密 —— Java代码手写+集成两种方式,手把手教学!保证能用!
本文提供了在数据库中对密码等敏感信息进行加盐加密的详细教程,包括手写MD5加密算法和使用Spring Security的BCryptPasswordEncoder进行加密,并强调了使用BCryptPasswordEncoder时需要注意的Spring Security配置问题。
210 0
数据库信息/密码加盐加密 —— Java代码手写+集成两种方式,手把手教学!保证能用!
|
3月前
|
安全 算法 数据安全/隐私保护
黑客克星!Python加密艺术大公开,AES、RSA双剑合璧,守护你的数字世界
在这个数据泛滥的时代,数字世界既充满了知识,也潜藏安全隐患。Python 作为强大的编程语言,以其独特的加密技术为我们的信息安全保驾护航。本文将介绍 AES 和 RSA 这两种加密算法,揭示它们如何协同工作,保护你的数字世界。AES(高级加密标准)以其高效、安全著称,能将敏感信息转化为难以破解的乱码。Python 的 `pycryptodome` 库让 AES 加密变得简单易行。然而,AES 面临密钥分发难题,此时 RSA(非对称加密算法)便大显身手,通过公钥加密、私钥解密的方式确保密钥传输安全。AES 与 RSA 在 Python 中交织成一道坚不可摧的防护网,共同守护我们的数字世界。
91 0
|
算法 Java 数据安全/隐私保护
【Java小工匠聊密码学】--对称加密--DES
1、 DES算法   DES对称加密,对称加密,是一种比较传统的加密方式,其加密运算、解密运算使用的是同样的密钥,信息的发送者和信息的接收者在进行信息的传输与处理时,必须共同持有该密码(称为对称密码),是一对称加密算法。
1475 0
|
1天前
|
Java
Java—多线程实现生产消费者
本文介绍了多线程实现生产消费者模式的三个版本。Version1包含四个类:`Producer`(生产者)、`Consumer`(消费者)、`Resource`(公共资源)和`TestMain`(测试类)。通过`synchronized`和`wait/notify`机制控制线程同步,但存在多个生产者或消费者时可能出现多次生产和消费的问题。 Version2将`if`改为`while`,解决了多次生产和消费的问题,但仍可能因`notify()`随机唤醒线程而导致死锁。因此,引入了`notifyAll()`来唤醒所有等待线程,但这会带来性能问题。
Java—多线程实现生产消费者
|
3天前
|
安全 Java Kotlin
Java多线程——synchronized、volatile 保障可见性
Java多线程中,`synchronized` 和 `volatile` 关键字用于保障可见性。`synchronized` 保证原子性、可见性和有序性,通过锁机制确保线程安全;`volatile` 仅保证可见性和有序性,不保证原子性。代码示例展示了如何使用 `synchronized` 和 `volatile` 解决主线程无法感知子线程修改共享变量的问题。总结:`volatile` 确保不同线程对共享变量操作的可见性,使一个线程修改后,其他线程能立即看到最新值。