android和java webservice RSA处理的不同

android和java webservice RSA处理的不同,第1张

1最近做RSA加密用于增强android客户机与服务器(JavaEE)数据传输的安全性。发现在andorid机器上生成的(密钥对由服务器在windows xp下生成并将公钥发给客户端保存)密码无法在服务器通过私钥解密。
2为了测试,在服务器本地加解密正常,另外,在android上加解密也正常,但是在服务器中加密(使用相同公钥)后的密码同样无法在android系统解密(使用相同私钥)。
3由于对RSA加密算法不了解,而且对Java RSA的加密过程也不清楚、谷歌一番,才了解到可能是加密过程中的填充字符长度不同,这跟加解密时指定的RSA算法有关系。
4比如,在A机中使用标准RSA通过公钥加密,然后在B系统中使用“RSA/ECB/NoPadding”使用私钥解密,结果可以解密,但是你会发现解密后的原文前面带有很多特殊字符,这就是在加密前填充的空字符;如果在B系统中仍然使用标准的RSA算法解密,这在相同类型的JDK虚拟机环境下当然是完全一样的,关键是android系统使用的虚拟机(dalvik)跟SUN标准JDK是有所区别的,其中他们默认的RSA实现就不同。
5更形象一点,在加密的时候加密的原文“abc”,你直接使用“abc”getBytes()方法获得的bytes长度可能只有3,但是系统却先把它放到一个512位的byte数组里,new byte[512],再进行加密。但是解密的时候你使用的是“加密后的密码”getBytes()来解密,解密后的原文自然就是512长度的数据,即是在“abc”之外另外填充了500多字节的其他空字符。
引用:
Afters some hours of trying, confirming that the key pairs are the same, using different options of saving the public key in the Android filesystem, etc I finally found a post stating that Android is using the Bouncycastle Security provider Bouncycastle’s default RSA implementation is: “RSA/None/NoPadding”, whereas Sun’s default security provider implementation is “RSA/None/PKCS1Padding” So, no decryption possible when just using
CiphergetInstance("RSA")
because of the different paddings used
So for a solution I downloaded the bouncycastle Jar, added bounycastle as a Security provider to my Java App, and now use
CiphergetInstance("RSA", "BC");
It works fine now
EOF这位仁兄分析说android系统的RSA实现是"RSA/None/NoPadding",而标准JDK实现是"RSA/None/PKCS1Padding" ,这造成了在android机上加密后无法在服务器上解密的原因(服务器使用的是SUN JDK60)。
我自己的总结:其实只要加载bouncycastle Jar到PC服务端和android客户端即可。
另外
KeyPairGenerator keyPairGen = KeyPairGeneratorgetInstance("RSA",
new orgbouncycastlejceproviderBouncyCastleProvider());
所有getInstantce方法里必须写成如上形式才可。
转载

RSA是一种非对称加密算法,常用来对传输数据进行加密,配合上数字摘要算法,也可以进行文字签名。

padding即填充方式,由于RSA加密算法中要加密的明文是要比模数小的,padding就是通过一些填充方式来限制明文的长度。后面会详细介绍padding的几种模式以及分段加密。

加密:公钥放在客户端,并使用公钥对数据进行加密,服务端拿到数据后用私钥进行解密;

加签:私钥放在客户端,并使用私钥对数据进行加签,服务端拿到数据后用公钥进行验签。

前者完全为了加密;后者主要是为了防恶意攻击,防止别人模拟我们的客户端对我们的服务器进行攻击,导致服务器瘫痪。

RSA使用“密钥对”对数据进行加密解密,在加密解密前需要先生存公钥(Public Key)和私钥(Private Key)。

公钥(Public key): 用于加密数据 用于公开, 一般存放在数据提供方, 例如iOS客户端。

私钥(Private key): 用于解密数据 必须保密, 私钥泄露会造成安全问题。

iOS中的Securityframework提供了对RSA算法的支持,这种方式需要对密匙对进行处理, 根据public key生成证书, 通过private key生成p12格式的密匙

首先我们要会生成RSA密钥文件,现在一步步的来给大家展示一下,如何生成我们所需的公钥和私钥文件:

$ openssl genrsa -out privatepem 1024

openssl:是一个自由的软件组织,专注做加密和解密的框架。

genrsa:指定了生成了算法使用RSA

-out:后面的参数表示生成的key的输入文件

1024:表示的是生成key的长度,单位字节(bits)

$ openssl req -new -key privatepem -out rsacertcsr

可以拿着这个文件去数字证书颁发机构(即CA)申请一个数字证书。CA会给你一个新的文件cacertpem,那才是你的数字证书。(要收费的)

$ openssl x509 -req -days 3650 -in rsacertcsr -signkey privatepem -out rsacertcrt

509是一种非常通用的证书格式。

将用上面生成的密钥privkeypem和rsacertcsr证书请求文件生成一个数字证书rsacertcrt。这个就是公钥

$ openssl x509 -outform der -in rsacertcrt -out rsacertder

注意: 在 iOS开发中,公钥是不能使用base64编码的,上面的命令是将公钥的base64编码字符串转换成二进制数据

在iOS使用私钥不能直接使用,需要导出一个p12文件。下面命令就是将私钥文件导出为p12文件。

$ openssl pkcs12 -export -out pp12 -inkey privatepem -in rsacertcrt

IOS客户端的加解密首先我们需要导入Securityframework,

在ios中,我们主要关注四个函数

RSA算法有2个作用一个是加密一个是加签。从这几个函数中,我们可以看到,我们第一种是使用公钥能在客户端:加密数据,以及服务器端用私钥解密。

第二个就是用私钥在客户端加签,然后用公钥在服务器端用公钥验签。第一种完全是为了加密,第二种是为了放抵赖,就是为了防止别人模拟我们的客户端来攻击我们的服务器,导致瘫痪。

(1)获取密钥,这里是产生密钥,实际应用中可以从各种存储介质上读取密钥 (2)加密 (3)解密

(1)获取密钥,这里是产生密钥,实际应用中可以从各种存储介质上读取密钥 (2)获取待签名的Hash码 (3)获取签名的字符串 (4)验证

(1)私钥用来进行解密和签名,是给自己用的。

(2)公钥由本人公开,用于加密和验证签名,是给别人用的。

(3)当该用户发送文件时,用私钥签名,别人用他给的公钥验证签名,可以保证该信息是由他发送的。当该用户接受文件时,别人用他的公钥加密,他用私钥解密,可以保证该信息只能由他接收到。

使用事例:

Demo链接

在对称密码中,由于加密和解密的密钥是相同的,因此必须向接收者配送密钥。用于解密的密钥必须被配送给接收者,这一问题称为 密钥配送问题 ,如果使用公钥密码,则无需向接收者配送用于解密的密钥,这样就解决了密钥配送问题。可以说公钥密码是密码学历史上最伟大的发明。

解决密钥配送问题的方法

在人数很多的情况下,通信所需要的密钥数量会增大,例如:1000名员工中每一个人都可以和另外999个进行通信,则每个人需要999个通信密钥,整个密钥数量:
1000 x 999 ÷ 2 = 499500
很不现实,因此此方法有一定的局限性

在Diffic-Hellman密钥交换中,进行加密通信的双方需要交换一些信息,而这些信息即便被窃听者窃听到也没有问题(后续文章会进行详解)。

在对称密码中,加密密钥和解密密钥是相同的,但公钥密码中,加密密钥和解密密钥却是不同的。只要拥有加密密钥,任何人都可以加密,但没有解密密钥是无法解密的。

公钥密码中,密钥分为加密密钥(公钥)和解密密钥(私钥)两种。

公钥和私钥是一一对应的,一对公钥和私钥统称为密钥对,由公钥进行加密的密文,必须使用与该公钥配对的私钥才能够解密。密钥对中的两个密钥之间具有非常密切的关系——数学上的关系——因此公钥和私钥是不能分别单独生成的。

发送者:Alice      接收者:Bob      窃听者:Eve
通信过程是由接收者Bob来启动的

公钥密码解决了密钥配送的问题,但依然面临着下面的问题

RSA是目前使用最广泛的公钥密码算法,名字是由它的三位开发者,即Ron Rivest、Adi Shamir和Leonard Adleman的姓氏的首字母组成的(Rivest-Shamir-Adleman)。RSA可以被使用公钥密码和数字签名(此文只针对公钥密码进行探讨,数字签名后续文章敬请期待)1983年在美国取得了专利,但现在该专利已经过期。

在RSA中,明文、密钥和密文都是数字,RSA加密过程可以用下列公式来表达

密文 = 明文 E mod N

简单的来说,RSA的密文是对代表明文的数字的 E 次方求mod N 的结果,换句话说:将明文和自己做 E 次乘法,然后将结果除以 N 求余数,这个余数就是密文。

RSA解密过程可以用下列公式来表达

明文 = 密文 D mod N
对表示密文的数字的 D 次方求mod N 就可以得到明文,换句话说:将密文和自己做 D 次乘法,在对其结果除以 N 求余数,就可以得到明文
此时使用的数字 N 和加密时使用的数字 N 是相同的,数 D 和数 N 组合起来就是RSA的解密密钥,因此 D 和 N 的组合就是私钥 。只要知道 D 和 N 两个数的人才能够完成解密的运算

根据加密和解密的公式可以看出,需要用到三个数—— E 、 D 和 N 求这三个数就是 生成密钥对 ,RSA密钥对的生成步骤如下:

准备两个很大的质数 p 和 q ,将这两个数相乘,结果就是 N
N = p x q

L 是 p-1 和 q-1 的最小公倍数,如果用lcm( X , Y )来表示 “ X 和 Y 的最小公倍数” 则L可以写成下列形式
L = lcm ( p - 1, q - 1)

E 是一个比1大、比 L 小的数。 E 和 L 的最大公约数必须为1,如果用gcd( X , Y )来表示 X 和 Y 的最大公约数,则 E 和 L 之间存在下列关系:
1 < E < L
gcd( E , L ) = 1 (是为了保证一定存在解密时需要使用的数 D )

1 < D < L
E x D mod L = 1

p = 17
q = 19
N = p x q = 17 x 19 = 323

L = lcm ( p - 1, q - 1) = lcm (16,18) = 144

gcd( E , L ) = 1
满足条件的 E 有很多:5,7,11,13,17,19,23,25,29,31
这里选择5来作为 E ,到这里我们已经知道 E = 5    N = 323 这就是公钥

E x D mod L = 1
D = 29 可以满足上面的条件,因此:
公钥: E = 5     N = 323
私钥: D = 29    N = 323

要加密的明文必须是小于 N 的数,这是因为在加密运算中需要求 mod N 假设加密的明文是123
明文 E mod N = 123 5 mod 323 = 225(密文)

对密文225进行解密
密文 D mod N = 225 29 mod 323 = 225 10 x 225 10 x 225 9 mod 323 = (225 10 mod 323) x (225 10 mod 323) x (225 9 mod 323) = 16 x 16 x 191 mod 323 = 48896 mod 323 = 123(明文)

如果没有mod N 的话,即:

明文 = 密文 D mod N

通过密文求明文的难度不大,因为这可以看作是一个求对数的问题。
但是,加上mod N 之后,求明文就变成了求离散对数的问题,这是非常困难的,因为人类还没有发现求离散对数的高效算法。

只要知道 D ,就能够对密文进行解密,逐一尝试 D 来暴力破译RSA,暴力破解的难度会随着D的长度增加而加大,当 D 足够长时,就不能再现实的时间内通过暴力破解找出数 D

目前,RSA中所使用的 p 和 q 的长度都是1024比特以上, N 的长度为2048比特以上,由于 E 和 D 的长度可以和N差不多,因此要找出 D ,就需要进行2048比特以上的暴力破解。这样的长度下暴力破解找出 D 是极其困难的

E x D mod L = 1           L = lcm ( p - 1, q - 1)
由 E 计算 D 需要使用 p 和 q ,但是密码破译者并不知道 p 和 q

对于RSA来说,有一点非常重要,那就是 质数 p 和 q 不能被密码破译这知道 。把 p 和 q 交给密码破译者与把私钥交给密码破译者是等价的。

p 和 q 不能被密码破译者知道,但是 N = p x q 而且 N 是公开的, p 和 q 都是质数,因此由 N 求 p 和 q 只能通过 将 N 进行质因数分解 ,所以说:
一旦发现了对大整数进行质因数分解的高效算法,RSA就能够被破译

这种方法虽然不能破译RSA,但却是一种针对机密性的有效攻击。

所谓中间人攻击,就是主动攻击者Mallory混入发送者和接收者的中间,对发送者伪装成接收者,对接收者伪装成发送者的攻击,在这里,Mallory就是“中间人”

这种攻击不仅针对RSA,而是可以针对任何公钥密码。在这个过程中,公钥密码并没有被破译,所有的密码算法也都正常工作并确保了机密性。然而,所谓的机密性并非在Alice和Bob之间,而是在Alice和Mallory之间,以及Mallory和Bob之间成立的。 仅靠公钥密码本身,是无法防御中间人攻击的。

要防御中间人攻击,还需要一种手段来确认所收到的公钥是否真的属于Bob,这种手段称为认证。在这种情况下,我们可以使用公钥的 证书 (后面会陆续更新文章来进行探讨)

网络上很多服务器在收到格式不正确的数据时都会向通信对象返回错误消息,并提示“这里的数据有问题”,然而,这种看似很贴心的设计却会让攻击者有机可乘。 攻击者可以向服务器反复发送自己生成的伪造密文,然后分析返回的错误消息和响应时间获得一些关于密钥和明文的信息。

为了抵御这种攻击,可以对密文进行“认证”,RSA-OAEP(最优非对称加密填充)正是基于这种思路设计的一种RSA改良算法。

RSA-OAEP在加密时会在明文前面填充一些认证信息,包括明文的散列值以及一定数量的0,然后用RSA进行加密,在解密的过程中,如果解密后的数据的开头没有找到正确的认证信息,则可以判定有问题,并返回固定的错误消息(重点是,不能将具体的错误内容告知开发者)
RSA-OAEP在实际应用中,还会通过随机数使得每次生成的密文呈现不同的排列方式,从而进一步提高安全性。

随着计算机技术的进步等,以前被认为是安全的密码会被破译,这一现象称为 密码劣化 ,针对这一点:

RSA公司致力开发双因素用户认证、加密和公钥管理系统,为有志开拓电子商务的企业建立安全稳妥的基础建设。

RSA作为领导全球的安全技术先驱,致力发展网络安全的三大核心领域,包括:


1、认证技术──RSASecurID®方案为领先市场的双因素用户认证技术。RSASecurID软件只容许经过认证的用户使用电子邮件系统、互联网服务器、本地网、广域网、网络 *** 作系统及其他资源,使宝贵的网络资源获得完善的保护。SecurID方案更广泛支持认证设备,包括时间同步的审核设备、智能卡,建立虚拟保护网,有效抵抗非法入侵,使网络资料免受意外造成的破坏及恶意入侵。


2、授权技术──RSAClearTrust®软件是统一权限管理的领导者,支持密码、数字证书、双因素令牌和目录服务器的认证方式,可以通过静态和动态的授权方式进行访问控制,同时能够实现单点登录,加强了Web服务器以及应用服务器的安全。


3、公钥基建──RSAKeon®公钥基建系列以可相互 *** 作及标准的公钥基建技术为基础,让用户有效管理数字认证过程,为经认证、专有及符合法律效力的电子通讯及交易建立安全的环境。RSAKeon软件系列 *** 作简易,可与其他标准的公钥基建为方案进行互 *** 作,配合RSASecurID的认证技术及RSABSAFE加密产品系列使用,可大大增强系统的保安能力。


4、加密技术──RSABSAFE®软件应用于目前最受欢迎的的互联网应用方案,包括互联网浏览器、无线设备、电子商务服务器、电子邮件系统及虚拟专用网络产品。RSABSAFE致力配合不同标准的需要,包括SSL、S/MIME、WTLS、IPSec及PKCS,能节省开发人员於开发工序的时间及所承受的风险,提供备受公认及稳定可靠的保安能力。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zz/10726842.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-10
下一篇 2023-05-10

发表评论

登录后才能评论

评论列表(0条)

保存