加入收藏 | 设为首页 | 会员中心 | 我要投稿 安卓应用网 (https://www.0791zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java加解密RSA使用方法代码示例

发布时间:2020-05-23 14:26:03 所属栏目:Java 来源:互联网
导读:最近为了分析一段请求流,不得不去研究一下RSA加密。首先,强调一点:密钥的“钥”读“yue”,不是“yao”,额。。。

最近为了分析一段请求流,不得不去研究一下RSA加密。

首先,强调一点:密钥的“钥”读“yue”,不是“yao”,额。。。

网上关于RSA的原理一抓一大把的,这里只是简单说说我的理解:

1. 两个足够大的互质数p,q;
2. 用于模运算的模 n=p*q;
3. 公钥KU(e,n)中的e满足 1<e< (p-1)(q-1),且与(p-1)(q-1)互质;
4. 密钥KR(d,n)中的d满足  d*e % (p-1)(q-1)= 1,%是取余运算。

因为公钥是公开的,所以我知道了e和n,那么根据2,3,4式子的关系,我们只要从n的值推出p,q的值则可计算出d的值,也就能找到密钥。

然而,关键就在这里, n=p*q,如果两个互质数p和q足够大,那么根据目前的计算机技术和其他工具,至今也没能从n分解出p和q,这是数学上的一个难题,也正是这个难题成为了RSA加密至今被广泛使用的原因。换句话说,只要密钥长度n足够大(一般1024足矣),基本上不可能从公钥信息推出私钥信息。

好了,这里作为研究的随笔,记录一下java如何使用,以下主要有三种方法,基本大同小异,只是获取公钥私钥的途径不一样就是了:

方法一:

利用KeyPairGenerator直接生成公钥和密钥,一般私钥保留给服务端,公钥交给客户端。

public class RSACryptography {
	public static String data="hello world";
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		KeyPair keyPair=genKeyPair(1024);
		//获取公钥,并以base64格式打印出来
		PublicKey publicKey=keyPair.getPublic();		
		System.out.println("公钥:"+new String(Base64.getEncoder().encode(publicKey.getEncoded())));
		//获取私钥,并以base64格式打印出来
		PrivateKey privateKey=keyPair.getPrivate();		
		System.out.println("私钥:"+new String(Base64.getEncoder().encode(privateKey.getEncoded())));
		//公钥加密
		byte[] encryptedBytes=encrypt(data.getBytes(),publicKey);	
		System.out.println("加密后:"+new String(encryptedBytes));
		//私钥解密
		byte[] decryptedBytes=decrypt(encryptedBytes,privateKey);		
		System.out.println("解密后:"+new String(decryptedBytes));
	}
	//生成密钥对
	public static KeyPair genKeyPair(int keyLength) throws Exception{
		KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance("RSA");
		keyPairGenerator.initialize(1024);		
		return keyPairGenerator.generateKeyPair();
	}
	//公钥加密
	public static byte[] encrypt(byte[] content,PublicKey publicKey) throws Exception{
		Cipher cipher=Cipher.getInstance("RSA");//java默认"RSA"="RSA/ECB/PKCS1Padding"
		cipher.init(Cipher.ENCRYPT_MODE,publicKey);
		return cipher.doFinal(content);
	}
	//私钥解密
	public static byte[] decrypt(byte[] content,PrivateKey privateKey) throws Exception{
		Cipher cipher=Cipher.getInstance("RSA");
		cipher.init(Cipher.DECRYPT_MODE,privateKey);
		return cipher.doFinal(content);
	}
}

运行结果:

公钥:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCSl6V7XNkVR9+NotekZm1FjHdL7oDqA66hrG5D/wgQ1XIF22mex7pnNc8PRBRScJQZJbzQ3ZnVmV5XqrVSCGbqaMPFmIXetu6lifQHoGptH9ghZsemanqp0sSd1TkHcPL2Njk/hZabWYBzPbjlidgfcMotehnFUdlIMGCusMV0awIDAQAB
私钥:MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJKXpXtc2RVH342i16RmbUWMd0vugOoDrqGsbkP/CBDVcgXbaZ7Humc1zw9EFFJwlBklvNDdmdWZXleqtVIIZupow8WYhd627qWJ9Aegam0f2CFmx6ZqeqnSxJ3VOQdw8vY2OT+FlptZgHM9uOWJ2B9wyi16GcVR2UgwYK6wxXRrAgMBAAECgYA8YBjX5jXCfgek3hzSqRz4OBIqQ+D0gO+7xrjjaHZ5+G8t2mB19Ozg9ViCgRednKBiexh5LcveHXytvrFPSAaagoa9DFKktaQmIQ15z3xXtgiHxg2dxDFJ1GNyhNjhMl8RSff2nSfQaRrgA8y36k0OZq240sdls6GbBMMoHRuRAQJBAOm6fw7cVXfmvzL0JBZmDl3SPK3sSNM6tfxaDy39W1g9rmGHKqs2XOubCe06ic/m9pxJnPmUXhgvYtiYLdC6NbkCQQCgj5O/sA0wYQQvW+WxQvleBLND9ZT2QOG5wvYRMoKP+uYE3SwsfKTZ1YsD5DjoyQPrc/lbCX7x+A8qRqLdRw1DAkAmhwJ4vaMtD5FG4e2s74fAuW4dMUzT3OKwxVupNhE/m3NKSlCjRmPMxpK9Ux/ycF0IaC4DCgz0qaL+lx8+P+OpAkA6Kol+AgtlIWBgv8wAYaDxPIas8gTbCTo9D7IRHNlLy7sUvANKwoT+HWxVJpKvUlNHMyZ8on4IrrLfv+M0go79AkAUwV5Nipi7ekScrzEMiaRJoYXgpFv2pQnRQzBQm5xVxtbuCpmuopNyk/9zm33RiwwjN6uYV9Hfg7e6HNsK2qIR
加密后:v?,Y9?`o^hmm_?$?p崃?4bhhN?25/?6Tw草遏鬼L&&*Q1OA祉@`剪啃`?>x/运A?HIGi?$B捞
?"ST
解密后:hello world

方法二:

实际上,方法一只是用来生成密钥就OK了,生成的密钥需要保存到本地文件中,所以一般不会在客户端调用KeyPairGenerator进行密钥的生成操作。

这里,我们可以将方法一得到的密钥保存到文件,下次我们直接读取就可以了。我假设以String的形式保存在文件内,那么接下来直接使用读取到的String生成密钥即可。

当然,你也可以使用openssl来生成也可以,不过我觉得麻烦就不弄了。

public class RSACryptography {
	public static String data="hello world";
	public static String publicKeyString="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCISLP98M/56HexX/9FDM8iuIEQozy6kn2JMcbZS5/BhJ+U4PZIChJfggYlWnd8NWn4BYr2kxxyO8Qgvc8rpRZCkN0OSLqLgZGmNvoSlDw80UXq90ZsVHDTOHuSFHw8Bv//B4evUNJBB8g9tpVxr6P5EJ6FMoR/kY2dVFQCQM4+5QIDAQAB";
	public static String privateKeyString="MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAIhIs/3wz/nod7Ff/0UMzyK4gRCjPLqSfYkxxtlLn8GEn5Tg9kgKEl+CBiVad3w1afgFivaTHHI7xCC9zyulFkKQ3Q5IuouBkaY2+hKUPDzRRer3RmxUcNM4e5IUfDwG//8Hh69Q0kEHyD22lXGvo/kQnoUyhH+RjZ1UVAJAzj7lAgMBAAECgYAVh26vsggY0Yl/Asw/qztZn837w93HF3cvYiaokxLErl/LVBJz5OtsHQ09f2IaxBFedfmy5CB9R0W/aly851JxrI8WAkx2W2FNllzhha01fmlNlOSumoiRF++JcbsAjDcrcIiR8eSVNuB6ymBCrx/FqhdX3+t/VUbSAFXYT9tsgQJBALsHurnovZS1qjCTl6pkNS0V5qio88SzYP7lzgq0eYGlvfupdlLX8/MrSdi4DherMTcutUcaTzgQU20uAI0EMyECQQC6il1Kdkw8Peeb0JZMHbs+cMCsbGATiAt4pfo1b/i9/BO0QnRgDqYcjt3J9Ux22dPYbDpDtMjMRNrAKFb4BJdFAkBMrdWTZOVc88IL2mcC98SJcII5wdL3YSeyOZto7icmzUH/zLFzM5CTsLq8/HDiqVArNJ4jwZia/q6Fg6e8KO2hAkB0EK1VLF/ox7e5GkK533Hmuu8XGWN6I5bHnbYd06qYQyTbbtHMBrFSaY4UH91Qwd3u9gAWqoCZoGnfT/o03V5lAkBqq8jZd2lHifey+9cf1hsHD5WQbjJKPPIb57CK08hn7vUlX5ePJ02Q8AhdZKETaW+EsqJWpNgsu5wPqsy2UynO";
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		//获取公钥 
		PublicKey publicKey=getPublicKey(publicKeyString);
		//获取私钥 
		PrivateKey privateKey=getPrivateKey(privateKeyString);		
		//公钥加密
		byte[] encryptedBytes=encrypt(data.getBytes(),privateKey);		
		System.out.println("解密后:"+new String(decryptedBytes));
	}
	//将base64编码后的公钥字符串转成PublicKey实例
	public static PublicKey getPublicKey(String publicKey) throws Exception{
		byte[ ] keyBytes=Base64.getDecoder().decode(publicKey.getBytes());
		X509EncodedKeySpec keySpec=new X509EncodedKeySpec(keyBytes);
		KeyFactory keyFactory=KeyFactory.getInstance("RSA");
		return keyFactory.generatePublic(keySpec);	
	}
	//将base64编码后的私钥字符串转成PrivateKey实例
	public static PrivateKey getPrivateKey(String privateKey) throws Exception{
		byte[ ] keyBytes=Base64.getDecoder().decode(privateKey.getBytes());
		PKCS8EncodedKeySpec keySpec=new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory=KeyFactory.getInstance("RSA");
		return keyFactory.generatePrivate(keySpec);
	}
	//公钥加密
	public static byte[] encrypt(byte[] content,privateKey);
		return cipher.doFinal(content);
	}
}

运行结果

加密后:.azaQ瘿unやASu@q??>?:sQ3?A_l'遥`t?6INK%IC尊[鹰#枋リG?1i	lX锇?"糍>Ij脶Z晦5uDqe悱sey冖Ud'LD%
解密后:hello world

方法三:

除了保存密钥字符串之外,其他的做法一般是只保存 模n(modulus),公钥和私钥的e和d(exponent)。

其中,n,e,d可以这样获取到,获取到后可以保存到本地文件中。

//获取公钥 
RSAPublicKey publicKey=(RSAPublicKey) getPublicKey(publicKeyString); 
BigInteger modulus1=publicKey.getModulus(); 
BigInteger exponent1=publicKey.getPublicExponent(); 
   
//获取私钥 
RSAPrivateKey privateKey=(RSAPrivateKey) getPrivateKey(privateKeyString);     
BigInteger modulus2=privateKey.getModulus(); 
BigInteger exponent2=privateKey..getPrivateExponent(); 

这里,假设我已经从文件中读取到了modulus和exponent:

public class RSACryptography {
	public static String data="hello world";
	public static String modulusString="95701876885335270857822974167577168764621211406341574477817778908798408856077334510496515211568839843884498881589280440763139683446418982307428928523091367233376499779842840789220784202847513854967218444344438545354682865713417516385450114501727182277555013890267914809715178404671863643421619292274848317157";
	public static String publicExponentString="65537";
	public static String privateExponentString="15118200884902819158506511612629910252530988627643229329521452996670429328272100404155979400725883072214721713247384231857130859555987849975263007110480563992945828011871526769689381461965107692102011772019212674436519765580328720044447875477151172925640047963361834004267745612848169871802590337012858580097";
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub		
		//由n和e获取公钥
		PublicKey publicKey=getPublicKey(modulusString,publicExponentString);
		//由n和d获取私钥
		PrivateKey privateKey=getPrivateKey(modulusString,privateExponentString);
		//公钥加密
		byte[] encryptedBytes=encrypt(data.getBytes(),privateKey);		
		System.out.println("解密后:"+new String(decryptedBytes));
	}
	//将base64编码后的公钥字符串转成PublicKey实例
	public static PublicKey getPublicKey(String modulusStr,String exponentStr) throws Exception{
		BigInteger modulus=new BigInteger(modulusStr);
		BigInteger exponent=new BigInteger(exponentStr);
		RSAPublicKeySpec publicKeySpec=new RSAPublicKeySpec(modulus,exponent);
		KeyFactory keyFactory=KeyFactory.getInstance("RSA");
		return keyFactory.generatePublic(publicKeySpec);
	}
	//将base64编码后的私钥字符串转成PrivateKey实例
	public static PrivateKey getPrivateKey(String modulusStr,String exponentStr) throws Exception{
		BigInteger modulus=new BigInteger(modulusStr);
		BigInteger exponent=new BigInteger(exponentStr);
		RSAPrivateKeySpec privateKeySpec=new RSAPrivateKeySpec(modulus,exponent);
		KeyFactory keyFactory=KeyFactory.getInstance("RSA");
		return keyFactory.generatePrivate(privateKeySpec);
	}
	//公钥加密
	public static byte[] encrypt(byte[] content,privateKey);
		return cipher.doFinal(content);
	}
}

(编辑:安卓应用网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读