范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

非对称加密之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("加解密异常");         }     } }
  同样,当我们看到 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字节数,不然就只能等着出现异常了。

吉林市四大名山都叫什么?龙潭山在吉林省吉林市东部,与小白山朱雀山及小团子山合称吉林四大名山。风景幽美,是个度假胜地。龙潭山是以位于西北角山麓一个称为龙潭的秀丽水池而得名。龙潭约长五十三公尺,约宽二十六公尺河北有哪些三本学校?菜鸟来谈谈吧,欢迎大家关注菜鸟!O现在已经慢慢取消三本院校或者独立院校这种说法了。现在的福独立院校要么转成民办的二本院校,要么成为职业类的技术学院。总之已经开始在取消了,大家都可以对方手机号加不上微信是为什么?有对方的手机号,但却无法通过搜索手机号添加对方的微信,可能的原因有一下几种1。对方的微信没有绑定手机号最早注册微信的时候,笔者记得直接用QQ号登录即可,时间有点久了,记得不是很确切为什么阴阳师的小小黑可以万攻满暴代替满暴高暴伤?其他式神不可以吗?哪个收益更高?小小黑万攻好还是高爆伤好?前提条件肯定是带针女御魂,针女御魂是暴击有40概率触发造成对方生命上限10,不超过攻击的120。黑童子大招特性生命低于70,2段99群攻生命低于40,3段生理需求与心理需求哪个重要还是都重要?人活在世上,是会有各种需求,各种需求都得到满足,那才叫活得痛苦!首先是物质需求,人要穿衣吃饭,无饭吃,要饿死,无衣穿,要冻死,所以,人把物质摆第一。什么是精神需求?非物质外的一种需马尚如果恢复理想的话,能否赶上第三阶段广东的比赛?马尚如果恢复理想的话,能否赶上第三阶段广东的比赛?先要搞清楚马尚布鲁克斯是什么伤病,马尚是跟腱断裂,是篮球运动员的治命伤,这和重伤要想恢复的好,也是凤毛麟角,很少很少,何况马尚布鲁怎么做能让一台用了8年的低配电脑保持流畅不卡顿?我家的电脑是2008年自己组装的,现在还在服役中,去年升级过一次硬件,现在运行挺流畅的。下文具体说一说。升级内存电脑运行速率的主要瓶颈是内存,无法匹配CPU的运行速率和越来越大的软有哪些化妆品和护肤品,你知道好用,但是用过之后才发现竟然这么好用?买东西最怕一头热!这边刚看完别人的推荐,那边就点开了某宝下单,等东西到了就后悔作为一个某宝VIP包年大户,我买东西必看人家的评论和使用体验!尤其是商品下面的评论,至少翻三页,只要差农村的空巢老人没有退休金,儿女出外打工,生活怎么解决?感谢邀请农村的空巢老人没有退休金,儿女外出打工,生活确实比较困难,幸亏国家对年满六十岁的老年人有照顾补贴,还有点承包地,不需要交农业税,国家还可以补贴,儿女们再给一点生活费用,这样为什么汽车过度保养也会对车不好?车主们都知道车要三分修,七分养,日常用车中,保养必不可少。不过很多车主因为爱车心切,难免落入过度保养的陷阱。那么,有哪些需要避免的车辆过度保养误区呢?机油频繁更换机油更换要根据车辆怎么评价粉身碎骨全不怕,要留清白在人间的于谦?德高望重我认为于谦是一个大英雄。在瓦剌进犯北京,明英宗在土木堡被俘虏,二十多万明军精锐丧失殆尽。瓦剌首领也先认为抓住明英宗是奇货可居,以英宗做人质要挟明朝各地守城将领就范,很多城池
44岁女星当街被喷不明液体!脸部眼睛遭化学性伤害,现场画面曝光1月19日,据台媒报道,44岁女星余筱萍当街被喷不明液体,消息一出,立马引起了网友们的关注。曝光的现场画面中,可以见到余筱萍驾驶着红色汽车出行,行经某条单行道时,她被前方货车挡住去兔子急了会咬人,戴璐老公决定跟韦某死磕的背后,是超级的不自信锤子啥时候装的摄像头?我觉得在发现水电费高时,很可能他就会调取监控,发现了老婆的情况!所以,在装摄像头之前,他已经看到对方是谁了。只是对方太强大!根本就惹不起!他纠结彷徨,他无奈无中国互联网的流量屏障能否被打破?题图视觉中国农历新年即将到来,各大品牌的春节营销越来越热闹。在凸显春节氛围的红色广告素材愈加频繁地出现在朋友圈信息流,其中暗藏的玄机也逐渐浮现可以直接跳转到品牌商家天猫店铺的链接越刘亦菲的妈妈刘晓莉两婚两离,至今单身,长得比女儿还漂亮文脏脏石榴编辑蒙面晓虾从十五岁出道至今,刘亦菲在娱乐圈中一直都是焦点的存在,从神雕侠侣的小龙女到天龙八部的王语嫣,这些人物都是大家心目中不可替代的神仙姐姐。刘亦菲纯天然的颜值,早已暨南大学化学与材料学院宁国宏李丹教授团队在Angew。Chem。发表重要成果近日,化学与材料学院宁国宏李丹教授团队以暨南大学为唯一通讯单位在AngewandteChemieInternationalEdition(IF16。8)上发表了题为AnAtomic中国式家长该学会放手也许适当选择的放手,通过引导和选择信息内容,让孩子在文学艺术的浸润中更有自主性地理解世界,或许更是一种收获。相关内容网络截图彩云网评特约评论员流川鑫近日,充满中国风的动画短片合集中这场爱的双向奔赴超暖!杭州不少幼儿园收到了家长们的感谢信钱江晚报小时新闻记者金丹丹通讯员杭教感谢幼儿园的老师们,帮我在这个特殊时期照看孩子,让我可以安心奋战在工作岗位上。近日,杭州市拱墅区舟山路幼儿园收到了一位医生妈妈的感谢信,信中特别那些子女没有成为人中龙凤的家长,孩子成年后,该如何自处?老话讲有缘千里来相会,朋友再远回来看你就是有缘。世界上那么多人,可是我们来往的就一少部分,这难道不是缘分?什么样的缘,才能够成为一家人?我们说,就是一个字业。提到业,第一印象会想到制止孩子早恋最有效的方法!家长注意了!发现孩子早恋后不可以简单粗暴的对待,不可以打骂孩子,毕竟是未成年人,逆反心理特别严重。这样做只会加大他的逆反心理。让他排斥你,认为你剥夺了他的真爱,要拆散他们。制止孩子早恋最有效的湖北人过年必吃的6大特色美食,鄂菜之魂,寓意兔年吉祥顺利2023年的春节即将来到,无论你在任何地方,只要条件允许,都要回家过年。大年三十的晚上,除夕年夜饭是中国最隆重最重要的一顿晚餐,全家坐在一起,吃团圆饭,迎接新年的到来。年夜饭是过年举报曝光专区畅通群众监督渠道胡泊为持续强化正风肃纪,营造风清气正节日氛围,中央纪委国家监委网站推出2023年元旦春节期间四风问题监督举报曝光专区,加大典型案例通报曝光力度,不断释放坚定不移严之又严的强烈信号。