R的极客理想系列文章,涵盖了R的思想,使用,工具,创新等的一系列要点,以我个人的学习和体验去诠释R的强大。
R语言作为统计学一门语言,一直在小众领域闪耀着光芒。直到大数据的爆发,R语言变成了一门炙手可热的数据分析的利器。随着越来越多的工程背景的人的加入,R语言的社区在迅速扩大成长。现在已不仅仅是统计领域,教育,银行,电商,互联网….都在使用R语言。
要成为有理想的极客,我们不能停留在语法上,要掌握牢固的数学,概率,统计知识,同时还要有创新精神,把R语言发挥到各个领域。让我们一起动起来吧,开始R的极客理想。
关于作者:
- 张丹,分析师/程序员/Quant: R,Java,Nodejs
- blog: http://blog.fens.me
- email: bsspirit@gmail.com
转载请注明出处:
http://blog.fens.me/r-crypto-aes-rsa/
前言
我们在日常的数据通信过程中,互联网各种应用软件,虽然让我们越来越方便,但也存在各种隐私泄露,数据被盗取的情况。基于我们对RSA、AES和证书的知识,结合R语言工具,自治一个数据通讯系统吧,保证自己在和别人传输数据过程中的数据隐私。
由于最近对密码学产生兴趣,让用R语言做一个密码学的访问,因此对R语言中openssl包进行了研究,本文为openssl的第四篇文章,用R语言实现RSA+AES混合加密。openssl的文章分别是,R语言进行非对称加密RSA,R语言进行AES对称加密,R语言配合openssl生成管理应用x509证书,用R语言实现RSA+AES混合加密
加密算法涉及到密码学的很多深入的知识,我并没有深入研究,本文只针对于openssl的使用,如果有任何与专业教材不符合的描述,请以专业教材为准。
目录
- 用openssl生成秘钥key
- RSA+AES混合加密
1. 用openssl生成秘钥key
用openssl包,有6种秘钥的生成方案,分别是aes秘钥,rsa秘钥,dsa秘钥,ec秘钥,x25519秘钥,ed25519秘钥。
- aes_keygen(length = 16),AES对称加密,只有一个秘钥。
- rsa_keygen(bits = 2048),RSA非对称加密,包括公钥和私钥。
- dsa_keygen(bits = 1024),DSA非对称加密,包括公钥和私钥。
- ec_keygen(curve = c(“P-256”, “P-384”, “P-521”)),椭圆曲线非对称加密,包括公钥和私钥。
- x25519_keygen(),非对称加密,包括公钥和私钥。
- ed25519_keygen(),非对称加密,包括公钥和私钥。
生成AES的秘钥
# 生成秘钥
> aes<-aes_keygen(length = 16);aes
aes e0:ad:28:fa:05:04:c0:6b:7c:ba:ad:f9:00:1d:44:22
# 查看结构
> str(aes)
'aes' raw [1:16] e0 ad 28 fa ...
生成RSA公钥和私钥
code> # 生成秘钥 > rsa<-rsa_keygen(bits = 2048);rsa [2048-bit rsa private key] md5: c4db98bb1d161082cc41b56b5863cce9 sha256: c4d58b626f4e7ebc20fe12830bd7e1b647ef12151672008eaf9bf709bdbeee50 # 查看结构 > str(rsa) List of 4 $ type : chr "rsa" $ size : int 2048 $ pubkey:List of 5 ..$ type : chr "rsa" ..$ size : int 2048 ..$ ssh : chr "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCt7BCaSxvC4UkPiDcwrZFgliC960t+uo+cGMRivq ..." ..$ fingerprint: 'hash' raw [1:32] c4 d5 8b 62 ... ..$ data :List of 2 .. ..$ e: 'bignum' raw [1:3] 01 00 01 .. ..$ n: 'bignum' raw [1:257] 00 ad ec 10 ... $ data :List of 8 ..$ e : 'bignum' raw [1:3] 01 00 01 ..$ n : 'bignum' raw [1:257] 00 ad ec 10 ... ..$ p : 'bignum' raw [1:129] 00 e7 61 0c ... ..$ q : 'bignum' raw [1:129] 00 c0 6d d7 ... ..$ d : 'bignum' raw [1:256] 2e 20 dc 4e ... ..$ dp: 'bignum' raw [1:128] 4b 61 43 ce ... ..$ dq: 'bignum' raw [1:129] 00 92 1c 55 ... ..$ qi: 'bignum' raw [1:129] 00 af 11 51 ... # 获得公钥 > rsa$pubkey [2048-bit rsa public key] md5: c4db98bb1d161082cc41b56b5863cce9 sha256: c4d58b626f4e7ebc20fe12830bd7e1b647ef12151672008eaf9bf709bdbeee50
其他的非对称加密算法的生成公钥和私钥的代码,与RSA的代码结构是一致的。
2. RSA+AES混合加密
在前面两篇文章中,我们已经分别掌握了AES对称加密技术和RSA非对称加密技术,两种技术其实都自己的特征和使用的场景。
- AES对称加密技术,加密和解密使用同一个密钥,加密速度快,密钥最长只有256个bit,执行速度快,易于硬件实现,但只有一个秘钥,一方泄露就会不安全。
- RSA非对称加密技术,使用公钥加密和私钥解密,加密速度慢,私钥长度可以设置1024bit,2048bit,4096bit,长度越长,越安全,但是生成密钥越慢,加解密也越耗时。
结合上面两种加密技术的特征,我们可以设计一套RSA+AES混合加密方案,让数据加密传输能够使用到两种技术的优点。
方案优势:
- 单纯的使用 RSA(非对称加密)方式的话,效率会很低,因为非对称加密解密方式虽然很保险,但是过程复杂,需要时间长;
- 但是,RSA 优势在于数据传输安全,且对于几个字节的数据,加密和解密时间基本可以忽略,所以用它加密 AES 秘钥(一般16个字节)再合适不过了;
- 单纯的使用 AES(对称加密)方式的话,死板且不安全。这种方式使用的密钥是一个固定的密钥,客户端和服务端是一样的,一旦密钥被人获取,那么,我们所发的每一条数据都会被都对方破解;
- 但是,AES有个很大的优点,那就是加密解密效率很高,而我们传输正文数据时,正号需要这种加解密效率高的,所以这种方式适合用于传输量大的数据内容;
我从互联网找了RSA+AES混合加密的一个设计思路,RSA+AES的混合加密时,AES用于给传输的数据加密,然后通过RSA给AES的秘钥加密,所以接收到数据后,就需要先解密得到AES的秘钥,然后通过AES秘钥再去解密得到数据。
操作步骤:
- 第1步,B系统:一次性,生成RSA私钥(rsa_key)和公钥(rsa_pubkey)。
- 第2步,A系统:一次性,生成AES秘钥(aes_key),获得把RSA公钥(rsa_pubkey),用RSA公钥对AES秘钥加密,生成(aes_key_mi)。
- 第3步,B系统:一次性,获得把加密后的AES秘钥(aes_key_mi),用RSA私钥(rsa_key)对AES私钥解密,得到(aes_key2)。
- 第4步,A系统:生成获得数据(dat)并进行序列化(dat_serial),用AES秘钥(aes_key)进行加密生成(dat_mi)
- 第5步,B系统:获得加密后的数据(dat_mi),用AES秘钥(aes_key2)进行解密(x_serial2),再反序列化获得原始数据(dat2)。
接下来,我们用R语言来模拟实现。
第一步,B系统:一次性,生成RSA私钥(rsa_key)和公钥(rsa_pubkey)。
# RSA私钥
> rsa_key <- rsa_keygen();rsa_key
[2048-bit rsa private key]
md5: 2fbb4bada8e942967577155c8d0e3251
sha256: 29e6aaabfd49fe884c505ed12130eb61d32090e8251503b2f69bb06a6c23c3c5
# RSA公钥
> rsa_pubkey <- rsa_key$pubkey; rsa_pubkey
[2048-bit rsa public key]
md5: 2fbb4bada8e942967577155c8d0e3251
sha256: 29e6aaabfd49fe884c505ed12130eb61d32090e8251503b2f69bb06a6c23c3c5
第2步,A系统:一次性,生成AES秘钥(aes_key),获得把RSA公钥(rsa_pubkey),用RSA公钥对AES秘钥加密,生成(aes_key_mi)。
# RSA公钥
> rsa_pubkey
[2048-bit rsa public key]
md5: 2fbb4bada8e942967577155c8d0e3251
sha256: 29e6aaabfd49fe884c505ed12130eb61d32090e8251503b2f69bb06a6c23c3c5
# AES秘钥
> aes_key <- aes_keygen();aes_key
aes d5:bf:bd:f0:6a:05:0b:f7:0d:04:4f:68:64:f5:7c:02
# 把AES秘钥加密
> aes_key_mi <- rsa_encrypt(aes_key, rsa_pubkey)
第3步,B系统:一次性,获得把加密后的AES秘钥(aes_key_mi),用RSA私钥(rsa_key)对AES私钥解密,得到(aes_key2)。
code> # 获得加密后的AES秘钥 > aes_key_mi # 用RSA私钥对AES私钥解密 > aes_key2<-rsa_decrypt(aes_key_mi,rsa_key);aes_key2 [1] d5 bf bd f0 6a 05 0b f7 0d 04 4f 68 64 f5 7c 02
第4步,A系统:生成获得数据(dat)并进行序列化(dat_serial),用AES秘钥(aes_key)进行加密生成(dat_mi)。
> # 原始数据
> dat<-iris[1:3,];dat
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
# 序列化
> dat_serial <- serialize(dat, NULL)
# 用AES秘钥进行加密生成
> dat_mi <- aes_cbc_encrypt(x_serial, key = aes_key)
第5步,B系统:获得加密后的数据(dat_mi),用AES秘钥(aes_key2)进行解密(x_serial2),再反序列化获得原始数据(dat2)。
# 获得加密数据
> dat_mi
# 解密
> dat_serial2<-aes_cbc_decrypt(dat_mi,aes_key2);x_serial2
# 反序列化
> dat2<-unserialize(x_serial2);dat2
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
有了本文的思路基础,接下来就可以自己设计一套软件程序了,把重要的信息加密,给对的人,也不怕中间过程被截获了。话说微信传输,已经没有隐私可言了,只能信自己了。
本文是介绍openssl包使用的第四篇文章,原想着R语言做密码学知识到哪天才能用上,没想到马上就用上了。
[…] 由于最近对密码学产生兴趣,让用R语言做一个密码学的访问,因此对R语言中openssl包进行了研究,本文为openssl的第三篇文章,R语言配合openssl生成管理应用x509证书。openssl的文章分别是,R语言进行非对称加密RSA,R语言进行AES对称加密,R语言配合openssl生成管理应用x509证书,用R语言实现RSA+AES混合加密。 […]
[…] 本文是介绍openssl包使用的第二篇文章,主要介绍AES算法的使用,还搭配了digest包做对比。虽然R语言不是专门做密码研究的工具,但实现个算法还是很方便的。作为数据分析师又学到了一些冷门知识,说不定哪天就会有用呢。openssl的文章分别是,R语言进行非对称加密RSA,R语言进行AES对称加密,R语言配合openssl生成管理应用x509证书,用R语言实现RSA+AES混合加密。 […]