密码学基础之RSA与不对称秘钥

本文主要通过RSA加解密实践,来讲述不对称秘钥的特点。

不对称秘钥和RSA

不对称秘钥算法,也叫公钥密码算法。
不对称秘钥算法图示:

不对称秘钥

不对称秘钥的重要特点是加密和解密用的秘钥不相同。

和对称秘钥算法的比较

不对称秘钥的优点
不对称秘钥有一个很大的好处是可以把公钥公开,比如Alice要传送敏感数据给Bob,Bob告诉Alice公钥,Alice用公钥加密数据,通过网络传送给Bob,在传送时被攻击者Eric捕获到,Eric拿到加密的数据和公钥,但不知道私钥仍无法破解敏感信息。

哦,这个看起来很不错,比对称加密好多了,完全可以取代对称加密呀?

等等!等等!小王同学,你先别激动,我们先了解下不对称秘钥的缺点再说。

不对称秘钥的缺点
不对称秘钥算法的原理并不复杂,可以从这篇文章对RSA算法的原理做大概的了解。
RSA等不对称秘钥算法都存在一个限制是——慢!这个从原理很容易知道。
慢会导致不对称秘钥算法另一个限制——只能加密少量数据。
RSA算法,一次加密的数据最多和秘钥长度相同。但实际上,RSA算法一般还需要有数据填充,比如常用的RSA_PKCS1_PADDING填充,还需要减去11个字节。
1024位秘钥,所能加密的数据长度为:1024 / 8 - 11 = 117字节。
不对称加密和对称加密同时用
如果你需要加密大量的数据,可以用对称加密,对称加密的秘钥用不对称加密算法加密保存。HTTPS就是这样做的。

不对称秘钥的其它用处

不对称秘钥除了可以用加密、解密还可以用于数字签名。本文不涉及数字签名的知识,主要讲述RSA加解密的使用。

RSA算法

生成秘钥

RSA的公钥和私钥需要配对,不能像对称加密的秘钥,可以随便写。
可以用OpenSSL生成RSA公钥和私钥

openssl genrsa -out private_key.pem 1024
openssl rsa -in private_key.pem -pubout -out public_key.pem
RSA公钥和私钥生成

public_key.pem和privte_key.pem都是文本文件,看下内容
public_key.pem

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD1t3KRf4oS3sH8PbABbXL1KBYC
nGq4C/yinpfQ2j2eUmZarHuwIMT9y5ns1lpZZTktGnypvnQjF8c0Rr/cYU53DJjg
lAgVEb3el6iU+WZ7nwLub/BNYS83zpzrhDE3Qy6qTM3evsUsekBR8x6f6Usl7KpE
I/0b+EfRSpXDdvU64wIDAQAB
-----END PUBLIC KEY-----

privte_key.pem

-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQD1t3KRf4oS3sH8PbABbXL1KBYCnGq4C/yinpfQ2j2eUmZarHuw
IMT9y5ns1lpZZTktGnypvnQjF8c0Rr/cYU53DJjglAgVEb3el6iU+WZ7nwLub/BN
YS83zpzrhDE3Qy6qTM3evsUsekBR8x6f6Usl7KpEI/0b+EfRSpXDdvU64wIDAQAB
AoGBAJK0odHfPTgBCf8pcaGYkG9xLJsIeutCNOd/GxOWif2yIux2WS8SkasaWd+/
J5iCSD32t4G9dafSNZyvtTPGYUqll4aGXlFqNW8pm16HPQXWrhv1D5LVEEu3zbj+
iNG+gHwB4bISQAOJbnvB6GoFUbDf8VYwkGGlSLGw5D5tulhRAkEA/XBLTfj+5j40
QPfuRIhcBsgxynKJDcmV0sLAIOTBIfSKs5nuYHEVEOcGaxS+nPY3w1ffSUPUdxm0
7L2s+9c0SQJBAPgzLLFvUjM58J/AtklkGyJ3KK5W+jLi/N1PIw7CGYGM2yfFiQLR
ibtJVjTFhLKqDz/BK4lZ9ffU/VNHSApOncsCQQCRBzSgnw9GtGv0jaxUnW+EFgWg
IyDYufW5kOafLCh1BNpmYnztxWhXrsyWdF2Ltr48U8mbxGwN57EIFJar2v+5AkA7
GkSMRAv48tUf1Y4Sz+m+PU3Mph2SPIcmVA/vFb1pIheV0u4bY7Y+iOokStychu52
qhMp8+gkie2BBTpcafgdAkBw8bAzLgmCV8SZEN60x8c2M2Y95CoYOoMLjvQdEfen
IeDmun3DtAPBuStwYNfeQnAHCwvcOJsgDiRLzhys3056
-----END RSA PRIVATE KEY-----

了解秘钥文件格式

你是否留意到这两个文件开头结尾的两行文字的区别了呢?比如:
public_key.pem的开头是

-----BEGIN PUBLIC KEY——

而rsa_private_key的开头是

-----BEGIN RSA PRIVATE KEY——

除了PUBLICPRIVATE区别外,后者还多了RSA
这表明这两个文件的格式不同。PKCS#1格式的RSA公钥、私钥文件开头和结束的两行带RSA字样,而PKCS#8格式不带。
有些RSA库,解密时需要PKCS#8格式的私钥文件,可以用下面的命令转换

openssl pkcs8 -topk8 -inform PEM -in private_key.pem -outform PEM -nocrypt>pkcs8_private_key.pem

加解密演示

1. Python RSA加解密演示

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5


def rsa_encrypt(plaintext, key):
    cipher = PKCS1_v1_5.new(RSA.importKey(key))
    return cipher.encrypt(plaintext)


def rsa_decrypt(ciphertext, key):
    cipher = PKCS1_v1_5.new(RSA.importKey(key))
    return cipher.decrypt(ciphertext, '')


if __name__ == '__main__':
    private_key = '''-----BEGIN RSA PRIVATE KEY-----
    MIICXQIBAAKBgQD1t3KRf4oS3sH8PbABbXL1KBYCnGq4C/yinpfQ2j2eUmZarHuw
    IMT9y5ns1lpZZTktGnypvnQjF8c0Rr/cYU53DJjglAgVEb3el6iU+WZ7nwLub/BN
    YS83zpzrhDE3Qy6qTM3evsUsekBR8x6f6Usl7KpEI/0b+EfRSpXDdvU64wIDAQAB
    AoGBAJK0odHfPTgBCf8pcaGYkG9xLJsIeutCNOd/GxOWif2yIux2WS8SkasaWd+/
    J5iCSD32t4G9dafSNZyvtTPGYUqll4aGXlFqNW8pm16HPQXWrhv1D5LVEEu3zbj+
    iNG+gHwB4bISQAOJbnvB6GoFUbDf8VYwkGGlSLGw5D5tulhRAkEA/XBLTfj+5j40
    QPfuRIhcBsgxynKJDcmV0sLAIOTBIfSKs5nuYHEVEOcGaxS+nPY3w1ffSUPUdxm0
    7L2s+9c0SQJBAPgzLLFvUjM58J/AtklkGyJ3KK5W+jLi/N1PIw7CGYGM2yfFiQLR
    ibtJVjTFhLKqDz/BK4lZ9ffU/VNHSApOncsCQQCRBzSgnw9GtGv0jaxUnW+EFgWg
    IyDYufW5kOafLCh1BNpmYnztxWhXrsyWdF2Ltr48U8mbxGwN57EIFJar2v+5AkA7
    GkSMRAv48tUf1Y4Sz+m+PU3Mph2SPIcmVA/vFb1pIheV0u4bY7Y+iOokStychu52
    qhMp8+gkie2BBTpcafgdAkBw8bAzLgmCV8SZEN60x8c2M2Y95CoYOoMLjvQdEfen
    IeDmun3DtAPBuStwYNfeQnAHCwvcOJsgDiRLzhys3056
    -----END RSA PRIVATE KEY-----'''
    public_key = '''-----BEGIN PUBLIC KEY-----
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD1t3KRf4oS3sH8PbABbXL1KBYC
    nGq4C/yinpfQ2j2eUmZarHuwIMT9y5ns1lpZZTktGnypvnQjF8c0Rr/cYU53DJjg
    lAgVEb3el6iU+WZ7nwLub/BNYS83zpzrhDE3Qy6qTM3evsUsekBR8x6f6Usl7KpE
    I/0b+EfRSpXDdvU64wIDAQAB
    -----END PUBLIC KEY-----'''
    message = 'RSA加解密演示'
    cipher_text = rsa_encrypt(message.encode(encoding="utf-8"), public_key)
    plain_text = rsa_decrypt(cipher_text, private_key)
    print(str(plain_text, encoding='utf-8'))

注意:对同样的公钥和明文进行RSA加密,秘文通常是不一样的,但这不影响解密。

2. iOS 前端加密,Python后端解密演示
私钥放在移动端是非常不安全的,攻击者可能破解你的iOS或Android程序找到私钥。很多时候,都是移动前端加密,后端解密。iOS 加密后用base64编码传送给后端,即使这个数据被攻击者捕获,也无法获取敏感数据。
iOS RSA加密可以借助Swift-RSAUtils开源库。
iOS代码中需要公钥需要去掉首行和末行内容。

func demo() {
    let text = "RSA加解密演示"
    let pubkey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD1t3KRf4oS3sH8PbABbXL1KBYC" +
            "nGq4C/yinpfQ2j2eUmZarHuwIMT9y5ns1lpZZTktGnypvnQjF8c0Rr/cYU53DJjg" +
            "lAgVEb3el6iU+WZ7nwLub/BNYS83zpzrhDE3Qy6qTM3evsUsekBR8x6f6Usl7KpE" + 
            "I/0b+EfRSpXDdvU64wIDAQAB"
    let encryptedData = RSAUtils.encryptWithRSAPublicKey(text.data(using: String.Encoding.utf8)!, pubkeyBase64: pubkey, keychainTag: "")
    if encryptedData != nil {
        let encryptedDataText = encryptedData!.base64EncodedString(options: NSData.Base64EncodingOptions())
        print("\(encryptedDataText)")
    } else {
        print("error")
    }
}

Python 解密

import base64
cipher_text_base64 = iOS提交过来的字符串
cipher_text = base64.b64decode(cipher_text_base64)
plain_text = rsa_decrypt(cipher_text, private_key)

相关文章

密码学基础之对称加密(一)
密码学基础系列

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343