• 关于RSA数字签名Android

    • 什么是RSA
    • 我自己的理解
      • 客户端请求服务器的数据
      • 服务器响应客户端的数据
    • 思路
    • 大概流程
    • 注意
    • 加密解密工具类的代码
    • 使用样例

关于RSA数字签名(Android)

近期项目中考虑到数据比较重要,担心与服务器交互过程中被篡改,所以引用了数据签名的技术。

什么是RSA:

RSA是一种非对称的加密算法,RSA的加密解密中有一对密钥(公钥和私钥),通过公钥加密的密文只能通过对应的私钥解密,反之亦然。

我自己的理解:

在数据交互中,必须同时知道密钥对和被加密的字符串(我们暂时先称为密签)的生成规则,才能造出合法的数据。下面假设我们的客户端代码被反编译,获取到了储存在我们本地的密钥对,我们分两种情况进行分析。

客户端请求服务器的数据

加密的密钥得到了,但是没有我们密签的生成规则,造不出合法的请求数据。

服务器响应客户端的数据

通过解密的私钥解密服务器返回的sign值,获取到了服务器响应数据的密签生成规则,但是加密响应数据的加密密钥是保存在服务器的,相对比较安全,所以也造不出合法的响应数据。

所以在这套加密体系中,请求数据的密签和响应数据的密签的生成规则应该是不同的。


思路:

在整个交互中一共有两对密钥,一对用于服务器的加密(公钥A)和客户端的解密(私钥A),另一对用于服务器的解密(私钥B)和客户端的加密(公钥B)。在客户端请求时,将请求数据通过RSA加密后连带要请求的数据一起发送给服务器,服务器收到请求后,首先通过对应的密钥对请求中加密的数据进行解密,然后对比解密后的内容与请求的内容是否一致,若一致,则可以判定数据是合法的,反之则是不合法的。服务器在响应客户端请求时,使用相同的方法。(Ps:请求的数据一般都是键值对,我们通过与服务器协商,使用相同的规则对数据进行拼接,组成一个字符串后进行加密)

大概流程:

这里假设我们的拼接规则是:键=值&键=值&…

Created with Raphaël 2.1.0 客户端 客户端 服务器 服务器 {"name":"张三", "age":"12", "sign":"这里是对数据进行拼接后加密的密文" (这里加密之前应该是:name=张三&age=12)} 服务器收到请求后取出sign的值进行解密, 然后通过拼接字符串的方式将出去sign的其 余参数按照规则拼接,如果拼接出来的值与 sign解密得到的值相同,则可以判断数据是 来自服务器的。 服务器的响应信息中也使用这样的加密方式, 客户端得到信息后,使用相同的方法判断 数据的合法性。

注意:

在加解密过程中,openssl生成的密钥对无法使用。(有大神发现问题希望指出)这里附上一对可用的钥匙。

—–BEGIN PUBLIC KEY—–
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBJq3d4HJscWh44l/Vh431rbKZ
XxdR+gRSgvINmCuHTlgasRsvKiPgtBtRsj/mzpowuxCOg67xkBQvIoXVs1wiJNuQ
Zi+mVXUQCJelLn5ykCLvNqkugMO9nNtre/2VezjP81t5FeOlEnQMo3AFLSeZv2cc
I9V0DD0IsnIlRH/L8wIDAQAB
—–END PUBLIC KEY—–

—–BEGIN PRIVATE KEY—–
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMEmrd3gcmxxaHji
X9WHjfWtsplfF1H6BFKC8g2YK4dOWBqxGy8qI+C0G1GyP+bOmjC7EI6DrvGQFC8i
hdWzXCIk25BmL6ZVdRAIl6UufnKQIu82qS6Aw72c22t7/ZV7OM/zW3kV46USdAyj
cAUtJ5m/Zxwj1XQMPQiyciVEf8vzAgMBAAECgYBaJ7G0BNWj5HN9KTzOME2ExSS+
DfKWovptgQ12Zva6W0kofE5R/3troOW3hlnpY7n40PfzbWe0/SlOrvCFRQjVXbbR
9a+eZ0xynSuMg8m57q8qHZ/l5dV8ECWsEUC1eFHepWpMDygFv8qgLIV2C5Ot03HW
yGXLzoPJ+GD9U+yA8QJBAP2vKm6Js9wYvK/vtUpX7jScuHHFSZmimoyAz3sOIWZ2
XBKspc0XDzLlIAd6BbC5i9JfTqTNJE0Om20NsuOqOp0CQQDC6g25Go56AZvsXPBh
1I5L0Lj673sBx9wqvAUS6/MCeJT9jBUq8FRDi4KVlkWBzhDP5K+AKnADm40fAVi2
R9PPAkBl2pOVyBH/16rClOLcE4vfceEYRNb1KXUV3o3vYVAFvJXhJZJ4Ur7Wd2ox
tktcllLOR1fjET529dtvoKVnhSx9AkEAsOr9dcyTEk8vlkVts37Zght8K9j/j8g3
IVr0SA5+zvlgUxu5gvYNphmVd+2kPYQrYmgynGTos32XhFMWkK11pQJAFOMAzgSE
PggBQohD4jg7vOvZzFO8M4VDee7yaC5xFpJlJBtol1twlIbzv1HjAgHDeqXChStf
rLegWG4sbnXTMA==
—–END PRIVATE KEY—–

加密解密工具类的代码

package com.shsy.test.rsa;import android.util.Base64;import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;import javax.crypto.Cipher;/*** Created by Shsy on 15-11-27.*/
public class RsaUtils {/*** 获取公钥** @param algorithm* @param bysKey* @return*/private static PublicKey getPublicKeyFromX509(String algorithm,String bysKey) throws NoSuchAlgorithmException, Exception {byte[] decodedKey = Base64.decode(bysKey, Base64.DEFAULT);X509EncodedKeySpec x509 = new X509EncodedKeySpec(decodedKey);KeyFactory keyFactory = KeyFactory.getInstance(algorithm);return keyFactory.generatePublic(x509);}/*** 获取私钥** @param key* @return* @throws Exception*/public static PrivateKey getPrivateKey(String key) throws Exception {byte[] keyBytes;keyBytes = Base64.decode(key, Base64.DEFAULT);PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance("RSA");PrivateKey privateKey = keyFactory.generatePrivate(keySpec);return privateKey;}/*** 使用公钥加密** @param content* @param publicKey* @return*/public static String encryptByPublic(String content, String publicKey) {try {PublicKey pubkey = getPublicKeyFromX509("RSA", publicKey);Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");cipher.init(Cipher.ENCRYPT_MODE, pubkey);byte plaintext[] = content.getBytes("UTF-8");byte[] output = cipher.doFinal(plaintext);String s = new String(Base64.encode(output, Base64.DEFAULT));return s;} catch (Exception e) {return null;}}/*** 通过私钥解密** @param content* @param privateKey* @return*/public static String decryptByPrivate(String content, String privateKey) {try {PrivateKey prikey = getPrivateKey(privateKey);Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");cipher.init(Cipher.DECRYPT_MODE, prikey);byte[] enBytes = Base64.decode(content, Base64.DEFAULT);byte[] deBytes = cipher.doFinal(enBytes);return new String(deBytes);} catch (Exception e) {return null;}}
}

使用样例

/**将上面的密钥复制到对应的""中*/
/**注意:密钥不包含被"-----BEGIN PUBLIC KEY-----"这样的头尾信息*/
/**加密的公钥*/
pivate final String public_Key="";
/**解密的私钥*/
pivate final String private_Key="";
/**要加密的内容*/
String s = "Test";
/**加密*/
String ss = RsaUtils.encryptByPublic(s,public_Key);
/**解密*/
String sss = RsaUtils.decryptByPrivate(ss,private_Key);

关于Android中RSA数字签名的理解及使用相关推荐

  1. Android中pendingIntent的深入理解

    pendingIntent字面意义:等待的,未决定的Intent. 要得到一个pendingIntent对象,使用方法类的静态方法 getActivity(Context, int, Intent, ...

  2. [转]Android中pendingIntent的深入理解

    转自;here pendingIntent字面意义:等待的,未决定的Intent. 要得到一个pendingIntent对象,使用方法类的静态方法 getActivity(Context, int, ...

  3. Android中RSA加密

    上次我们说了一个MD5加密,我们来复习一下.这是一种单向加密方式.我们只能让拦截我们数据的人不知道我们真实的内容是什么,但是我们不能反向解密.一般用于信息验证的场合.今天说的就是一个可以加密也可以解密 ...

  4. android 中MIME类型的理解

    初始MIME类型,是在学习ContentProvider的时候. 当在创建自己的ContentProvider的时,需要从抽象类ContentProvider中派生出自己的子类,并实现其中5个抽象方法 ...

  5. android中的数字签名技术

    数字签名利用非对称加密技术和消息摘要技术来保证信息的安全可靠.发送方需要提供签名文件和数字证书,接收者才可以解密出对应的数据.数字证书同样也可以认为是一个数字签名,只不过签名的内容是消息发送方的公钥 ...

  6. Android 中的LayoutInflater的理解

    LayoutInflater与findViewById的区别? 对于一个已经载入的界面,就可以使用findViewById()方法来获得其中的界面元素. 对于一个没有被载入或者想要动态载入的界面,就需 ...

  7. Android中measure过程、WRAP_CONTENT详解以及xml布局文件解析流程浅析(上)

    在之前一篇博文中<< Android中View绘制流程以及invalidate()等相关方法分析>> ,简单的阐述 了 Android View 绘制流程的三个步骤,即: 1. ...

  8. Android中Cursor类的概念和用法

    使用过 SQLite数据库的童鞋对 Cursor 应该不陌生,加深自己和大家对Android 中使用 Cursor 的理解. 关于 Cursor 在你理解和使用 Android Cursor 的时候你 ...

  9. Android 中关于Cursor类的介绍

    来自:http://www.cnblogs.com/TerryBlog/archive/2010/07/05/1771459.html 使用过 SQLite 数据库的童鞋对 Cursor 应该不陌生, ...

最新文章

  1. php防止注入漏洞,php防止sql注入漏洞代码
  2. Toping Kagglers:Bestfitting,目前世界排名第一
  3. MySQL:行锁、表锁、乐观锁、悲观锁、读锁、写锁
  4. axure如何实现跳转_Axure教程:网易云音乐首页原型设计
  5. Web程序员的Mysql进阶序一之sql使用分类及基础
  6. html原生上传,一个基于HTML5及原生JS的文件上传组件--JohnUploader
  7. 性能测试oracle瓶颈定位,性能测试中如何定位性能瓶颈
  8. 作为相亲大户,程序猿为何普遍单身?
  9. 《麦肯锡方法》读书笔记12
  10. 《大型网站技术架构-核心原理与案例分析》(李智慧 著)第3章-大型网站核心架构要素
  11. PHP:回退(Backed)枚举
  12. 基础SQL语法及使用(入门级)
  13. virtualbox 不能为虚拟电脑打开一个新任务/VT-x features locked or unavailable in MSR.
  14. linux服务器下搭建svn服务器仓库
  15. 安卓与苹果盒子与h5相互调用,js,vue
  16. 问渠哪得清如许?为有源头活水来。——AI与传统文化会碰撞出何种火花呢?
  17. 批量静默卸载软件工具制作
  18. Windows10系统下JDK1.8的下载安装及环境变量配置
  19. 以太(Aether)假说的破灭
  20. 转载 一篇职场裸文,虚伪被撕得一丝不挂

热门文章

  1. Mybatis-Plus配置和使用
  2. Win10怎么看内存条频率
  3. Kubernetes 为何称为 K8s?
  4. 001 计算思维-卡内基梅隆大学计算机系主任周以真(英汉对照版)
  5. hdu 1757(矩阵快速幂)
  6. 利用OpenCV实现欧拉数的计算
  7. 句柄php,什么是PHP句柄
  8. 一文学会回溯算法解题技巧
  9. 初学者之蚂蚁蜜蜂分类报错记录
  10. JBoot 全网上最好用的 API 文档工具