RSA

RSA加密原理超经典解析链接:
http://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.html
http://www.ruanyifeng.com/blog/2013/07/rsa_algorithm_part_two.html
密码算法应用规范
规则:使用RSA算法时要选取合适的公共指数e

说明:公共指数e位长越小,RSA加密或签名校验时的效率越高。但位长过小时(如e=3)可能会遭受一系列安全攻击[1]。如e=3时,若两不同消息m1、m2都使用RSA加密且使用相同的模N,当m1和m2满足某些特定的关系m1=ƒ(m2) mod N 时,攻击者有可能恢复出m1和m2

规则:使用RSA算法进行加密操作时,应优先选择OAEP填充方式

说明:对数据进行填充要非常谨慎,因为一些有经验的黑客有可能从中找到一些线索。早期的PKCS#1填充标准就曾受到一种自适应选择明文攻击的威胁。RSA实验室在PKCS#1 V1.5以后的标准中增加了OAEP(Optimal Asymmetric Encryption Padding)填充模式,可以有效阻止这类威胁。一般算法库提供的接口函数中都会有填充方式选择参数,如OpenSSL中为RSA_PKCS1_OAEP_PADDING

规则:使用RSA算法时,加密和签名要使用不同的密钥对

说明:RSA算法的通常用法是用对方的公钥进行加密,用自己的私钥进行签名。当加密和签名使用相同的密钥对时,如果签名时没有进行哈希,实际上是对数据进行了解密的操作。这样如果攻击者让密钥所有者对一段密文进行签名,他就得到了相应的明文。

另外,加密和签名的密钥对的管理方式和使用时限不同。用于验证签名的公钥需要长期有效,而用于签名的私钥在有效期之后必须销毁。用于解密的私钥需要长期有效, 而用于加密的公钥在有效期之后需要销毁。

2 非对称加密的基本流程

这里写图片描述
1)乙方生成两把密钥(公钥和私钥)。公钥是公开的,任何人都可以获得,私钥则是保密的。

2)甲方获取乙方的公钥,然后用它对信息加密。

3)乙方得到加密后的信息,用私钥解密。

3 应用场景
这里写图片描述
对称加密一般来讲速度比较慢,一般会结合AES等对称加密来使用;因为RSA的安全性性比较高,而AES又面临者密钥保存难的风险,所有在客户端和服务器交互的过程中,一般会使用RSA的方式,协商当前的AES密钥的方式;

package rsa_encrytion;



import java.io.ByteArrayOutputStream;

import java.security.Key;

import java.security.KeyFactory;

import java.security.KeyPair;

import java.security.KeyPairGenerator;

import java.security.NoSuchAlgorithmException;

import java.security.interfaces.RSAPrivateKey;

import java.security.interfaces.RSAPublicKey;

import java.security.spec.PKCS8EncodedKeySpec;

import java.security.spec.X509EncodedKeySpec;

import java.util.HashMap;

import java.util.Map;



import javax.crypto.Cipher;



public class RSA_Test {



         private static  final String KEY_ALGORITH = "RSA/ECB/OAEPWithSHA-256AndMGF1Padding";     //这里应该OAEP

         private static final String PUBLICKEY = "RSAPublicKey";

         private static final String PRIVATEKEY = "RSAPrivateKey";  

         private static final int MAX_ENCRYT_BLOCK = 245;        

         private static final int MAX_DECRYT_BLOCK = 256;



         //生成密钥对



         public static Map<String,Object> genkeyPair () throws NoSuchAlgorithmException {

                   KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITH);

                   keyPairGen.initialize(2048);

                   KeyPair keyPair = keyPairGen.generateKeyPair();

                   RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();

                   RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();



                   Map<String,Object> keyMap = new HashMap<String,Object>(2);

                   keyMap.put(PUBLICKEY, rsaPublicKey);

                   keyMap.put(PRIVATEKEY, rsaPrivateKey);



                   return keyMap;



         }



         //公玥加密     

         public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {

                   byte[] keyBytes = Base64Utils.decode(publicKey);

                   X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);

                   KeyFactory keyfactory = KeyFactory.getInstance(KEY_ALGORITH);

                   Key publicK = keyfactory.generatePublic(x509KeySpec);

                   Cipher cipher = Cipher.getInstance(keyfactory.getAlgorithm());

                   cipher.init(Cipher.ENCRYPT_MODE, publicK);   



                   ByteArrayOutputStream out = new ByteArrayOutputStream();

                   int inputLen = data.length;

                   int offset = 0;

                   byte[] cache;

                   int i = 0;



                   while(inputLen - offset > 0) {

                            if(inputLen - offset > MAX_ENCRYT_BLOCK) {

                                     cache = cipher.doFinal(data,offset,MAX_ENCRYT_BLOCK);

                            }

                            else {

                                     cache = cipher.doFinal(data,offset,inputLen - offset);

                            }



                            out.write(cache, 0, cache.length);

                            i++;

                            offset = i * MAX_ENCRYT_BLOCK;                           

                   }



                   byte[] byteEncryptData = out.toByteArray();

                   out.close();

                   return byteEncryptData;               

         }        



         //私玥解密     

         public static byte[] decryptByPrivateKey(byte[] encodedData, String privateKey) throws Exception {

                   byte[] keyBytes = Base64Utils.decode(privateKey);

                   PKCS8EncodedKeySpec  pkcs8KeySpec  = new PKCS8EncodedKeySpec(keyBytes);

                   KeyFactory keyfactory = KeyFactory.getInstance(KEY_ALGORITH);

                   Key privateK = keyfactory.generatePrivate(pkcs8KeySpec);

                   Cipher cipher = Cipher.getInstance(keyfactory.getAlgorithm());

                   cipher.init(Cipher.DECRYPT_MODE, privateK);



                   ByteArrayOutputStream out = new ByteArrayOutputStream();

                   int inputLen = encodedData.length;            

                   int offset = 0;

                   byte[] cache;

                   int i = 0;



                   while(inputLen - offset > 0) {

                            if(inputLen - offset > MAX_DECRYT_BLOCK) {

                                     cache = cipher.doFinal(encodedData,offset,MAX_DECRYT_BLOCK);

                            }

                            else {

                                     cache = cipher.doFinal(encodedData,offset,inputLen - offset);

                            }



                            out.write(cache, 0, cache.length);

                            i++;

                            offset = i * MAX_DECRYT_BLOCK;                            

                   }



                   byte[] bytedecryptData = out.toByteArray();

                   out.close();

                   return bytedecryptData;                

         }        

    //获取公玥

         public static String getPublicKey(Map<String,Object> mapkey) throws Exception {

                   Key key = (Key) mapkey.get(PUBLICKEY);

                   return Base64Utils.encode(key.getEncoded());                             

         }

         //获取私玥

         public static String getPrivateKey(Map<String,Object> mapkey) throws Exception {

                   Key key = (Key) mapkey.get(PRIVATEKEY);

                   return Base64Utils.encode(key.getEncoded());                             

         }



         public static void main(String[] args) {

                   // TODO Auto-generated method stub               

                   String publicKey,privateKey;

                   try {

                            Map<String,Object> keymap = genkeyPair();

                            publicKey = getPublicKey(keymap);

                            privateKey = getPrivateKey(keymap);

                            System.out.println("公玥:" + publicKey);

                            System.out.println("私玥:" + privateKey);



                            String plaintext  = "我们要对这段文字开始加密,加密使用的算法是RSA,大家注意看好了";

                            System.out.println("加密明文为:" + plaintext);

                            byte[] data = plaintext.getBytes();

                            byte[] encodedData = encryptByPublicKey(data,publicKey);

                            System.out.println("加密密文为:" + new String(encodedData)); 



                            byte[] decodedData = decryptByPrivateKey(encodedData, privateKey);

                            System.out.println("解密明文为:" + new String(decodedData));

                   } catch (Exception e) {

                            // TODO Auto-generated catch block

                            e.printStackTrace();

                   }

         }

}

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值