当前位置:首页 > 经验 >

rsa加密步骤(rsa加密方法怎么进行的)

来源:原点资讯(www.yd166.com)时间:2022-10-30 01:49:06作者:YD166手机阅读>>

对称加密和非对称加密

在说 RSA 之前,我们得先来说说这个什么事对称加密,什么又是非对称加密?

对称加密指的就是加密和解密使用同一个秘钥,所以叫对称加密。对称加密只有一个秘钥,作为私钥。

非对称加密指的是:加密和解密使用不同的秘钥,一把作为公开的公钥,另一把作为私钥。公钥加密的信息,只有私钥才能解密。

那么对称加密和非对称加密之间又有什么区别呢?

  • 对称加密中加密和解密使用的秘钥是同一个;非对称加密中采用两个密钥,一般使用公钥进行加密,私钥进行解密。
  • 对称加密解密的速度比较快,非对称加密和解密花费的时间长、速度相对较慢。
  • 对称加密的安全性相对较低,非对称加密的安全性较高。

今天我们来讲的就是非对称加密中的 RSA 加密。

RSA加密是什么?

RSA加密是一种非对称加密。可以在不直接传递密钥的情况下,完成解密。这能够确保信息的安全性,避免了直接传递密钥所造成的被破解的风险。是由一对密钥来进行加解密的过程,分别称为公钥和私钥。

通常情况下个人保存私钥,公钥是公开的(可能同时多人持有)。

虽然私钥是根据公钥决定的, 但是,我们是没有办法根据公钥来推算出私钥来的。

为提高保密强度,RSA密钥至少为500位长。这就使加密的计算量很大。为减少计算量,在传送信息时,常采用传统加密方法与公开密钥加密方法相结合的方式,即信息采用改进的DES或IDEA对话密钥加密,然后使用RSA密钥加密对话密钥和信息摘要。对方收到信息后,用不同的密钥解密并可核对信息摘要

RSA的加密过程

RSA的加密过程其实并不复杂,

(1)A生成一对密钥(公钥和私钥),私钥不公开,A自己保留。公钥为公开的,任何人可以获取。

(2)A传递自己的公钥给B,B用A的公钥对消息进行加密。

(3)A接收到B加密的消息,利用A自己的私钥对消息进行解密。

在这个过程中,只有2次传递过程,第一次是A传递公钥给B,第二次是B传递加密消息给A,即使都被其他人截获,也没有危险性,因为只有A的私钥才能对消息进行解密,防止了消息内容的泄露。

但是大家有没有想过,如果我们的消息被截获了,虽然没有被解密出来,但是如果说我们的公钥被拦截,然后将假指令进行加密,然后传递给A,这不就凉凉了?那数据是不是就不能称之为安全了?

不,RSA还有签名的过程。

签名过程如下:

(1)A生成一对密钥(公钥和私钥),私钥不公开,A自己保留。公钥为公开的,任何人可以获取。

(2)A用自己的私钥对消息加签,形成签名,并将加签的消息和消息本身一起传递给B。

(3)B收到消息后,在获取A的公钥进行验签,如果验签出来的内容与消息本身一致,证明消息是A回复的。

但是问题又来了,虽然截获的消息不能被篡改,但是消息的内容可以利用公钥验签来获得,并不能防止泄露。

那么应该怎么用呢?

其实这就显的并不是很好理解了 我们是不是可以这么设计:

A和B都有一套自己的公钥和私钥,当A要给B发送消息时,先用B的公钥对消息加密,再对加密的消息使用A的私钥加签名,达到既不泄露也不被篡改,更能保证消息的安全性。

那么 Java 代码怎么实现 RSA 的呢?代码如下:

import java.io.byteArrayOutputStream; 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 javax.crypto.Cipher; import org.apache.commons.codec.binary.Base64; public class TestRSA { /** * RSA最大加密明文大小 */ private static final int MAX_ENCRYPT_BLOCK = 117; /** * RSA最大解密密文大小 */ private static final int MAX_DECRYPT_BLOCK = 128; /** * 获取密钥对 * * @return 密钥对 */ public static KeyPair getKeyPair() throws Exception { KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA"); generator.initialize(1024); return generator.generateKeyPair(); } /** * 获取私钥 * * @param privateKey 私钥字符串 * @return */ public static PrivateKey getPrivateKey(String privateKey) throws Exception { KeyFactory keyFactory = KeyFactory.getInstance("RSA"); byte[] decodedKey = Base64.decodeBase64(privateKey.getBytes()); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKey); return keyFactory.generatePrivate(keySpec); } /** * 获取公钥 * * @param publicKey 公钥字符串 * @return */ public static PublicKey getPublicKey(String publicKey) throws Exception { KeyFactory keyFactory = KeyFactory.getInstance("RSA"); byte[] decodedKey = Base64.decodeBase64(publicKey.getBytes()); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedKey); return keyFactory.generatePublic(keySpec); } /** * RSA加密 * * @param data 待加密数据 * @param publicKey 公钥 * @return */ public static String encrypt(String data, PublicKey publicKey) throws Exception { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); int inputLen = data.getBytes().length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offset = 0; byte[] cache; int i = 0; // 对数据分段加密 while (inputLen - offset > 0) { if (inputLen - offset > MAX_ENCRYPT_BLOCK) { cache = cipher.doFinal(data.getBytes(), offset, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(data.getBytes(), offset, inputLen - offset); } out.write(cache, 0, cache.length); i ; offset = i * MAX_ENCRYPT_BLOCK; } byte[] encryptedData = out.toByteArray(); out.close(); // 获取加密内容使用base64进行编码,并以UTF-8为标准转化成字符串 // 加密后的字符串 return new String(Base64.encodeBase64String(encryptedData)); } /** * RSA解密 * * @param data 待解密数据 * @param privateKey 私钥 * @return */ public static String decrypt(String data, PrivateKey privateKey) throws Exception { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] dataBytes = Base64.decodeBase64(data); int inputLen = dataBytes.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offset = 0; byte[] cache; int i = 0; // 对数据分段解密 while (inputLen - offset > 0) { if (inputLen - offset > MAX_DECRYPT_BLOCK) { cache = cipher.doFinal(dataBytes, offset, MAX_DECRYPT_BLOCK); } else { cache = cipher.doFinal(dataBytes, offset, inputLen - offset); } out.write(cache, 0, cache.length); i ; offset = i * MAX_DECRYPT_BLOCK; } byte[] decryptedData = out.toByteArray(); out.close(); // 解密后的内容 return new String(decryptedData, "UTF-8"); } /** * 签名 * * @param data 待签名数据 * @param privateKey 私钥 * @return 签名 */ public static String sign(String data, 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(data.getBytes()); return new String(Base64.encodeBase64(signature.sign())); } /** * 验签 * * @param srcData 原始字符串 * @param publicKey 公钥 * @param sign 签名 * @return 是否验签通过 */ 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(Base64.decodeBase64(sign.getBytes())); } public static void main(String[] args) { try { // 生成密钥对 KeyPair keyPair = getKeyPair(); String privateKey = new String(Base64.encodeBase64(keyPair.getPrivate().getEncoded())); String publicKey = new String(Base64.encodeBase64(keyPair.getPublic().getEncoded())); System.out.println("私钥:" privateKey); System.out.println("公钥:" publicKey); // RSA加密 String data = "待加密的文字内容"; String encryptData = encrypt(data, getPublicKey(publicKey)); System.out.println("加密后内容:" encryptData); // RSA解密 String decryptData = decrypt(encryptData, getPrivateKey(privateKey)); System.out.println("解密后内容:" decryptData); // RSA签名 String sign = sign(data, getPrivateKey(privateKey)); // RSA验签 boolean result = verify(data, getPublicKey(publicKey), sign); System.out.print("验签结果:" result); } catch (Exception e) { e.printStackTrace(); System.out.print("加解密异常"); } } }

同样,当我们看到 RSA 的 Java实现的时候,我们就看到了他的缺点,上来就先定义最大加密明文大小和最大解密密文大小,那么这个 117 是怎么来的?

Java 默认的 RSA 加密实现不允许明文长度超过密钥长度减去 11(单位是字节,也就是 byte)。也就是说,如果我们定义的密钥(我们可以通过 java.security.KeyPairGenerator.initialize(int keysize) 来定义密钥长度)长度为 1024(单位是位,也就是 bit),生成的密钥长度就是 1024位 / 8位/字节 = 128字节,那么我们需要加密的明文长度不能超过 128字节 -11 字节 = 117字节。也就是说,我们最大能将 117 字节长度的明文进行加密,否则会出问题( javax.crypto.IllegalBlockSizeException: Data must not be longer than 53 bytes 的异常)。

那么我们使用 RSA 的时候应该注意什么内容呢?

1.加密的系统不要具备解密的功能,否则 RSA 可能不太合适,

因为这样即使黑客攻破了加密系统,他拿到的也只是一堆无法破解的密文数据。

2.生成密文的长度和明文长度无关,但明文长度不能超过密钥长度

不管明文长度是多少,RSA 生成的密文长度总是固定的。但是明文长度不能超过密钥长度。

也就是上面说的那个117字节数,不然就只能等着出现异常了。

栏目热文

rsa加密和解密的公式(rsa算法的加密和解密步骤)

rsa加密和解密的公式(rsa算法的加密和解密步骤)

一、前言在经历了人生的很多至暗时刻后,你读到了这篇文章,你会后悔甚至愤怒:为什么你没有早点写出这篇文章?!你的至暗时刻包...

2022-10-30 01:53:07查看全文 >>

rsa加密算法图解(rsa加密算法通俗解释)

rsa加密算法图解(rsa加密算法通俗解释)

RSA加密算法是目前最有影响力的公钥加密算法,并且被普遍认为是目前最优秀的公钥方案之一。RSA是第一个能同时用于加密和...

2022-10-30 02:10:02查看全文 >>

rsa加密解密教程(rsa算法的加密和解密步骤)

rsa加密解密教程(rsa算法的加密和解密步骤)

Python3 RSA加密解密封装1.RSA简介RSA公开密钥密码体制是一种使用不同的加密密钥与解密密钥,“由已知加密密...

2022-10-30 02:05:10查看全文 >>

rsa加密解密计算实例(rsa 加密算法数学原理)

rsa加密解密计算实例(rsa 加密算法数学原理)

加密——RSA前端与后台的加密与解密什么是RSA加密RSA加密算法是一种非对称加密算法,所谓非对称,就是指该算法需要一对...

2022-10-30 02:25:24查看全文 >>

刚安装的led大灯左边有黑影怎么调(led大灯透镜中间有黑影怎么调节)

刚安装的led大灯左边有黑影怎么调(led大灯透镜中间有黑影怎么调节)

1.尽管天花板或镜子上方位置的灯具安置即可满足基本照明需求,但可能会产生阴影或眩光,这对剃须或化妆来说并不理想。这时,需...

2022-10-30 02:24:38查看全文 >>

rsa非对称加密流程(RSA非对称加密)

rsa非对称加密流程(RSA非对称加密)

专注于IT行业优质技术服务号,欢迎关注作者:我叫Vincent密码学是在编码与破译的斗争实践中逐步发展起来的,并随着先进...

2022-10-30 02:04:22查看全文 >>

rsa加密模式(rsa加密过程图)

rsa加密模式(rsa加密过程图)

接口数据使用了 RSA 加密和签名?一篇文章带你搞定!1、前言 很多童鞋在工作中,会遇到一些接口使用RSA加密和签名来...

2022-10-30 02:22:00查看全文 >>

rsa加密原理图解(rsa加密解密的实际例子)

rsa加密原理图解(rsa加密解密的实际例子)

加密和解密使用的是两个不同的秘钥,这种算法叫做非对称加密。非对称加密又称为公钥加密,RSA只是公钥加密的一种。 数字签...

2022-10-30 02:24:59查看全文 >>

非对称密钥加密解密过程(对称式加密解密过程图解)

非对称密钥加密解密过程(对称式加密解密过程图解)

2022年在合肥举办的国家网络安全宣传周网络全博览会上,国盾量子和科大讯飞还联合推出了一种让保障我们老百姓切身利益的黑科...

2022-10-30 02:25:04查看全文 >>

rsa加密和解密过程(rsa加密解密的实际例子)

rsa加密和解密过程(rsa加密解密的实际例子)

1. RSA加密与解密 -- 使用公钥加密、私钥解密public class RSATool{public string...

2022-10-30 02:08:52查看全文 >>

文档排行