Android和IOS关于RSA加密以及服务端解密的研究实现

一、  密钥对的生成

RSA加密解密,类似于支付宝中的加解密功能,以前的app使用的是DES加密即对称加密算法,只需要一个密钥;而采用RSA实现加解密需要一个密钥对,即公钥和私钥。所以首先要做的操作是生成一个密钥对,在window 7环境下,这里借用支付宝demo中的openssl命令行工具,毕竟是通用的,密钥对的生成流程大致如下:

1、生成RSA私钥

<span style="white-space:pre">	</span>genrsa -out rsa_private_key.pem 1024

2、将RSA私钥转换成PKCS8格式,然后在命令行模式下复制到txt文件,供最后解密使用(服务端使用pem私钥解密)

<span style="white-space:pre">	</span>(1)pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt
	(2)pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -out rsa_private_key_pkcs8.pem -nocrypt

3、生成RSA pem格式公钥(Android使用pem公钥加密)

<span style="white-space:pre">	</span>rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

4、根据私钥(注:或者是pkcs8编码下的pem,即2(2))生成csr文件,这里面会输入相关地址及公司密码信息等

<span style="white-space:pre">	</span>(1)req -new -key rsa_private_key.pem -out company.csr
<pre name="code" class="java"><span style="white-space:pre">	</span>(2)req -new -key rsa_private_key_pkcs8.pem -out company.csr

5、根据私钥(注:可能是2(2))以及csr文件生成一个10年有效期的der格式公钥(IOS使用der公钥加密)

<span style="white-space:pre">	</span>x509 -req -in company.csr -out rsa_public_key.der -outform der -signkey rsa_private_key.pem -days 3650

二、Android加密过程的实现

加密使用公钥,不过Android使用的是pem公钥,IOS使用的是der公钥,以下是Android平台下加密方法,把一个字符串用公钥加密后得到一个byte数组,然后使用base64编码得到一个字符串返回,作为传递给服务端的参数(声明:encryptByPublicKey这个方法不是原创)

<span style="white-space:pre">	</span>public static String toEncryptStr(String param) {
		// TODO Auto-generated method stub
		try {
			System.out.println("加密前:" + param);
			byte[] data = param.getBytes();
			byte[] encodedData = encryptByPublicKey(data,
					RSAConfig.RSA_PUBLIC);
			String encryptStr = Base64Utils.encode(encodedData);
			System.out.println("加密后:" + encryptStr);
			return encryptStr;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}

	public static byte[] encryptByPublicKey(byte[] data, String publicKey)
			throws Exception {
		byte[] keyBytes = Base64Utils.decode(publicKey);
		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA",
				new org.bouncycastle.jce.provider.BouncyCastleProvider());
		Key publicK = keyFactory.generatePublic(x509KeySpec);
		// 对数据加密
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm(),
				new org.bouncycastle.jce.provider.BouncyCastleProvider());
		cipher.init(Cipher.ENCRYPT_MODE, publicK);
		int inputLen = data.length;
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		int offSet = 0;
		byte[] cache;
		int i = 0;
		// 对数据分段加密
		while (inputLen - offSet > 0) {
			if (inputLen - offSet > 117) {
				cache = cipher.doFinal(data, offSet, 117);
			} else {
				cache = cipher.doFinal(data, offSet, inputLen - offSet);
			}
			out.write(cache, 0, cache.length);
			i++;
			offSet = i * 117;
		}
		byte[] encryptedData = out.toByteArray();
		out.close();
		return encryptedData;
	}

三、服务端解密过程的实现

解密使用私钥,正好和加密的流程相反,不过目前技术水平来说,只能不同平台分开解密

	public static String toDecryptStr(String param) {
		// TODO Auto-generated method stub
		try {
			System.out.println("解密前:" + param);
			byte[] data = Base64Utils.decode(param);
			byte[] decodedData = decryptByPrivateKeyForAndroid(data,
					RSAConfig.RSA_PRIVATE);
			String target = new String(decodedData, "utf-8");
			System.out.println("解密后:" + target);
			return target;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}

	public static byte[] decryptByPrivateKeyForAndroid(byte[] encryptedData,
			String privateKey) throws Exception {
		byte[] keyBytes = Base64Utils.decode(privateKey);
		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA",
				new org.bouncycastle.jce.provider.BouncyCastleProvider());
		Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm(),
				new org.bouncycastle.jce.provider.BouncyCastleProvider());
		cipher.init(Cipher.DECRYPT_MODE, privateK);
		int inputLen = encryptedData.length;
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		int offSet = 0;
		byte[] cache;
		int i = 0;
		// 对数据分段解密
		while (inputLen - offSet > 0) {
			if (inputLen - offSet > 128) {
				cache = cipher.doFinal(encryptedData, offSet, 128);
			} else {
				cache = cipher
						.doFinal(encryptedData, offSet, inputLen - offSet);
			}
			out.write(cache, 0, cache.length);
			i++;
			offSet = i * 128;
		}
		byte[] decryptedData = out.toByteArray();
		out.close();
		return decryptedData;
	}

	public static byte[] decryptByPrivateKeyForIOS(byte[] encryptedData,
			String privateKey) throws Exception {
		byte[] keyBytes = Base64Utils.decode(privateKey);
		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.DECRYPT_MODE, privateK);
		int inputLen = encryptedData.length;
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		int offSet = 0;
		byte[] cache;
		int i = 0;
		// 对数据分段解密
		while (inputLen - offSet > 0) {
			if (inputLen - offSet > 128) {
				cache = cipher.doFinal(encryptedData, offSet, 128);
			} else {
				cache = cipher
						.doFinal(encryptedData, offSet, inputLen - offSet);
			}
			out.write(cache, 0, cache.length);
			i++;
			offSet = i * 128;
		}
		byte[] decryptedData = out.toByteArray();
		out.close();
		return decryptedData;
	}

加解密过程中主要使用了两个第三方jar包:bcprov-jdk15-140.jar、javabase64-1.3.1.jar

结束语:大功告成,在借鉴各位大神提供的加解密思路以及方法的前提下,加上个人的不断调试,终于实现了加解密过程;

附录:参考博文地址

java中RSA加解密的实现 http://www.open-open.com/lib/view/open1388369746625.html

Android RSA加密解密 http://blog.csdn.net/BBLD_/article/details/38777491

java与IOS之间的RSA加解密 http://yuur369.iteye.com/blog/1769395

ios下使用rsa算法与php进行加解密通讯 http://blog.yorkgu.me/2011/10/27/rsa-in-ios-using-publick-key-generated-by-openssl/

java中RSA加解密的实现 http://blog.csdn.net/centralperk/article/details/8558678

android和java webservice RSA处理的不同 http://blog.sina.com.cn/s/blog_4bce4aa301011p8x.html

OpenSSL小结http://www.cnblogs.com/phpinfo/archive/2013/08/09/3246376.html

时间: 2024-08-12 22:57:49

Android和IOS关于RSA加密以及服务端解密的研究实现的相关文章

Javascript端加密java服务端解密

通常我们会通过htts来保证传输安全,但如果我们不用https,如何通过javascript来保证浏览器端发送的参数进行加密,并且通过RSA算法来处理. 这里我们可以利用jquery的一个加密插件jcryption来处理,可以参考 http://jcryption.org/#examples 现在版本是3.0 但是没有java端的实现,下次有时间再研究.现在这个用的是1.1的版本 这个可以在 http://linkwithweb.googlecode.com/svn/trunk/Utilitie

Android版网络办公系统应用客户端+服务端

该项目源码是Android版网络办公系统应用客户端+服务端,也是一个简单的网上办公系统的Android客户端,项目有服务端和客户端部分的源码的,客户端开发环境eclipse  AVD版本 4.0服务器 phpStudy 2013集成环境 Apache+php5.3+ISAPI模式 phpStudy 2013集成环境绿色版下载http://www.phpstudy.net/phpstudy/phpStudy2013d.zip官网   http://www.phpstudy.net/ android

android上传图片、视频、文件,服务端使用wcf接收

最近一直在搞android上传图片.视频.文件,服务端使用wcf接收,本文对调试中的遇到的问题进行记录. 首先android上传一些小图片是比较容易的一天下来差不多就能调试出来,但是上传一些大的文件时就出现各种问题,包括wcf默认支持64k的文件,后来大图片可以上传了,但是传视频又有问题,上传的视频打不开,经过努力google最后问题终于解决了.作者kwstu QQ806693619 以下是调试代码:原文链接:http://www.kwstu.com/ArticleView/kwstu_2013

[PHP]AES加密----PHP服务端和Android客户端

本文采取128位AES-CBC模式加密和解密 1.首先对服务端安装mcrypt: sudo apt-get install php5-mcrypt php5-dev sudo php5enmod mcrypt sudo service apache2 restart 2.PHP服务端AES加密类代码 class MCrypt { private $iv = 'fedcba9876543210'; //初始化向量iv public $key;//AES加密的密钥key //将密钥$key传进本类

通过ios实现RSA加密和解密

在加密和解密中,我们需要了解的知识有什么事openssl:RSA加密算法的基本原理:如何通过openssl生成最后我们需要的der和p12文件. 废话不多说,直接写步骤: 第一步:openssl来生成公钥和私钥证书,最后需要得到公钥证书和私钥证书 . 这是在mac OX系统下显示的证书,如果我们用文本编辑器打开它,会发现里面是----BEGIN RSA 开头  并且----END RSA 结尾的一串字符串. 第二步:我们需要在代码中写我们的加密和机密方法,加密的字符串通过公钥进行加密,加密后的字

浅谈android Socket 通信及自建ServerSocket服务端常见问题

摘  要:TCP/IP通信协议是可靠的面向连接的网络协议,它在通信两端各建立一个Socket,从而在两端形成网络虚拟链路,进而应用程序可通过可以通过虚拟链路进行通信.Java对于基于TCP协议的网络通信提供了良好的封装,使用Socket对象代表两端的通信接口,通过Socket产生I/O流进行网络通信. 自建ServerSocket服务端时可能因PC与手机平板终端未接入同一路由器,因此无法访问服本地IP,可以尝试以下两种方式解决 关键词: Socket; ServerSocket;本地IP; ad

Android应用源码图书馆管理系统带服务端数据库

本项目是一套基于安卓的图书馆管理系统,包括jsp服务端源码,安卓客户端源码和mysql数据库.代码比较简单,供学习anroid与j2ee交互.例如Sqlite的使用.安卓客户端与jsp的web服务端的交互不错的全套完整源码.已包括服务端,搭个Tomcat环境就可以,非常简单. Code.rar

Android、iOS系统全部支持的移动端车牌识别

移动端车牌车牌识别的应用背景 随着经济水平的不断提升,汽车数量的爆炸式激增为汽车管理带来了一定的困难.现在,车牌识别已经成为每个城市的车辆管理重点工作之一,有效.准确.及时的车牌识别可以方便警务人员的交通执法.停车场车辆管理等工作.伴随着智能终端以及4G技术的快速普及与发展,移动互联网时代已经全面爆发,推出了"离线车牌识别软件-慧号通车牌识别",完美集成车牌识别算法,为智慧停车客户提供全套停车产业链的产品支撑和技术服务. 移动端车牌识别软件特点 1.识别速度快 "只需扫一扫,

ios客户端RSA公钥加密 .net后台私钥解密解决方案(基于Openssl)

1.需要后台提供.pem格式的Openssl公钥文件,也可以自己制作.具体请参考:http://www.qmailer.net/archives/216.html(OpenSSL密钥相关命令) char *my_encrypt(const char *str,const char *path_key){ char *p_en; RSA *p_rsa; FILE *file; int flen,rsa_len; if((file=fopen(path_key,"r"))==NULL){