您现在的位置是:IT资讯 >>正文
非对称加密之RSA是怎么加密的
IT资讯126人已围观
简介前几天阿粉刚刚说了这个 MD5 加密的前世今生,因为 MD5 也确实用的人不是很多了,阿粉就不再继续的一一赘述了,今天阿粉想给大家分享的,是非对称加密中的一种,那就是 RSA 加密算法。对称加密和非对 ...
前几天阿粉刚刚说了这个 MD5 加密的非对前世今生,因为 MD5 也确实用的称加人不是很多了 ,阿粉就不再继续的密之密一一赘述了 ,今天阿粉想给大家分享的非对 ,是称加非对称加密中的一种,那就是密之密 RSA 加密算法。
对称加密和非对称加密在说 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("加解密异常"); } }}1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.39.40.41.42.43.44.45.46.47.48.49.50.51.52.53.54.55.56.57.58.59.60.61.62.63.64.65.66.67.68.69.70.71.72.73.74.75.76.77.78.79.80.81.82.83.84.85.86.87.88.89.90.91.92.93.94.95.96.97.98.99.100.101.102.103.104.105.106.107.108.109.110.111.112.113.114.115.116.117.118.119.120.121.122.123.124.125.126.127.128.129.130.131.132.133.134.135.136.137.138.139.140.141.142.143.144.145.146.147.148.149.150.151.152.153.154.155.156.157.158.159.160.161.162.163.164.165.166.167.168.169.170.171.172.173.174.175.176.177.178.179.180.181.182.183.184.185.186.187.188.189.190.191.同样,当我们看到 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 你了解了么?
Tags:
转载:欢迎各位朋友分享到网络,但转载请说明文章出处“商站动力”。http://www.noorid.com/news/70a999920.html
相关文章
安全风险攻击面管理如何提升企业网络弹性?
IT资讯从研究人员近些年的调查结果来看,威胁攻击者目前非常善于识别和利用最具有成本效益的网络入侵方法,这就凸显出了企业实施资产识别并了解其资产与整个资产相关的安全态势的迫切需要。目前来看,为了在如此复杂的网络 ...
【IT资讯】
阅读更多主流大语言模型集体曝出训练数据泄露漏洞
IT资讯论文指出,当前绝大多数大语言模型的记忆训练数据)可被恢复,无论该模型是否进行了所谓的“对齐”。黑客可以通过查询模型来有效提取训练数据,甚至无需事先了解训练数据集。研究者展示了如何从Pythia或GPT ...
【IT资讯】
阅读更多“邪恶版”ChatGPT 出现:毫无道德限制,专为“网络罪犯”而生?
IT资讯近几个月来,伴随着 ChatGPT 的热度暴涨,OpenAI 也不断因 AI 的道德问题和数据安全隐患遭到多方质疑,甚至上周还受到了美国联邦贸易委员会FTC)的正式调查——这也是美国监管机构首次正式发 ...
【IT资讯】
阅读更多
热门文章
最新文章
友情链接
- SKG抽油烟机质量评测(全面分析SKG抽油烟机的性能与可靠性)
- X270在双核CPU中的性能表现(探索X270在双核CPU中的优势和应用场景)
- 华为Mate9拍摄视频全方位评测(华为Mate9拍视频功能强大,画质出色,满足各类拍摄需求)
- 使用Mac分区U盘安装Win10系统教程(详解Mac电脑如何分区U盘并安装Windows10系统)
- Root之后手机的变化及影响(探索手机root后的功能和风险)
- 如何评估数据中心?高度互联的生态系统是关键
- 探究惠普导航的优势与应用(解密惠普导航的功能和使用体验)
- 小米膜的优点和特点(为你的手机屏幕保驾护航)
- 京品电源(京品电源的)
- 小辣椒JDPlus全方位解读,值得购买吗?(便宜好用的小辣椒JDPlus手机,性价比之王!) 香港物理机云服务器网站建设源码库企业服务器亿华云b2b信息平台