浏览 10916 次
锁定老帖子 主题:Digest and Encrypt
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2010-11-01
最后修改:2011-03-21
这是10月31日 slide 上想写上去而没有写上去的部分 ……
因为 ppt 主要想写写 1.9.2 的一些改变,但是貌似 openssl 还是和 1.0 不太兼容,现在用的 0.9.8 只有椭圆函数电子签名可以用,椭圆函数加密还是很不方便。 要澄清的第一点:像 md5, sha1 之类的应该说是摘要算法,不是加密算法。 摘要算法是不能从结果还原的,往往结果长度固定,便于比较和验证。 加密算法是可以从结果还原的,密文长度随着输入的长度而增长。 这个知识库文章将摘要算法说成“单向加密” —— 是完全错误的 …… 单向加密指的是非对称加密算法,不要混淆了概念。 摘要算法 我们常用的有 CRC32(32), MD5(128), SHA1(160), RMD160(160), SHA2(256,384,512),括号中为摘要长度,以 bit 为单位,其中 CRC32 的结果为 32 位整数 由于 RMD160 结果长度和 SHA1 相同,而速度相应慢一点,用的人就比较少了。 但是有时用比较罕见的算法反而能增加安全性。 除了 CRC32 以外的摘要算法都有几种使用方法: digest 输出2进制表示的结果 hexdigest 16进制字符表示的结果,可用文本传输 base64digest 2进制结果的base64编码,可用文本传输 # coding:utf8 # 用 zlib 的 CRC32 require 'zlib' Zlib.crc32 'abcd' module Digest; end include Digest require 'digest/md5' MD5.digest 'abcd' require 'digest/sha1' SHA1.hexdigest 'abcd' require 'digest/rmd160' RMD160.base64digest 'abcd' require 'digest/sha2' SHA256.digest 'abcd' SHA384.hexdigest 'abcd' SHA512.base64digest 'abcd' 双向加密算法 双向加密算法,也称作对称键加密算法。 双向加密算法的特点是加密用的 算法 / key 和解密用的 算法 / key 很容易相互转换,甚至完全相同,只要知道其中一个,另一个很容易就能算出来。 最简单的双向加密算法就是 rot13,常用在论坛发帖时避免被搜索引擎或者 spam 收集信息 …… 所谓 rot,就是 rotate 的缩写,将 26 个字母用 13 位之后的替换掉。 rot13 的加密和解密算法就是同一个。 Ruby 标准库里没有明摆的 rot13,但是可以使用 nkf 的 rot13/rot47 require 'nkf' def rot13 s NKF.nkf '-r -s', s end rot13 'abcd' #=> "nopq" rot13 rot13 'abcd' #=> "abcd" 顺带一提,nkf 还有些好用的转换功能,像 line-ending 转换和某些编码转换。 NKF.guess 可以检测一些日文编码和 utf-8/utf-16。但是没有 tellenc 之类的工具能猜的编码多。 最常用的双向加密算法是 base64,因为 base64 的密文可以用纯 ascii 文本传输,所以广泛应用在很多文本协议上。中文邮件一般就是以 base64 密文来发送的。pem 格式就通过base64 保存公钥 / 密钥,便于网络传输。 再顺带一提,RFC4648 还提了一个 base32,它是大小写不敏感的,我用纯 Ruby 实现了一个: http://github.com/luikore/rfc-base32 Base64 的使用灰常简单: require 'base64' puts s = Base64.encode64 '这个可以有' #=> 1eK49r/J0tTT0A== puts Base64.decode64 s #=> 这个可以有 真正 "Hardcore" 一点的加密算法,就需要密钥(key)了。 基本要求是:不知道 key 就无法破译密文。 加密的过程: 把输入分成很多个固定大小的 block(如256byte), 对每块使用可逆函数计算出一个新的字节 block, 写到输出。 这个做法还有一点点问题,因为相同的输入可以获得相同的输出,从结果中就很容易看出哪两个 block 是完全一样的,就存在被猜出密钥的危险了。 解决方案之一是 Cipher Block Chaining (CBC),CBC 方法需要 Initialization Vector(IV)。 关于 CBC 等名词详见 wiki: Block Cipher Modes of Operation 使用 AES 加密的示例如下: require "openssl" cipher = OpenSSL::Cipher::Cipher # AES, block size = 256,使用 CBC aes = cipher.new('aes-256-cbc').encrypt # 随机生成密钥 key = aes.random_key # 随机生成初始向量 iv = aes.random_iv crypted = aes.update 'hello ' crypted.<< aes.update 'world' crypted.<< aes.final aes = cipher.new('aes-256-cbc').decrypt aes.key = key aes.iv = iv result = aes.update crypted result.<< aes.final puts result #=> "hello world" 查看有多少种可以用的对称加密算法: require "openssl" puts OpenSSL::Cipher::Cipher.ciphers.uniq(&:upcase) AES-128-CBC AES-128-CFB AES-128-CFB1 AES-128-CFB8 AES-128-ECB AES-128-OFB AES-192-CBC AES-192-CFB AES-192-CFB1 AES-192-CFB8 AES-192-ECB AES-192-OFB AES-256-CBC AES-256-CFB AES-256-CFB1 AES-256-CFB8 AES-256-ECB AES-256-OFB AES128 AES192 AES256 BF BF-CBC BF-CFB BF-ECB BF-OFB CAST CAST-cbc CAST5-CBC CAST5-CFB CAST5-ECB CAST5-OFB DES DES-CBC DES-CFB DES-CFB1 DES-CFB8 DES-ECB DES-EDE DES-EDE-CBC DES-EDE-CFB DES-EDE-OFB DES-EDE3 DES-EDE3-CBC DES-EDE3-CFB DES-EDE3-CFB1 DES-EDE3-CFB8 DES-EDE3-OFB DES-OFB DES3 DESX DESX-CBC IDEA IDEA-CBC IDEA-CFB IDEA-ECB IDEA-OFB RC2 RC2-40-CBC RC2-64-CBC RC2-CBC RC2-CFB RC2-ECB RC2-OFB RC4 RC4-40 blowfish 注: BF 为 blowfish,使用 64bit block 加密。 单向加密算法 单向加密算法也称非对称(键)加密算法,指的是就算你知道解密用的密钥,也几乎不可能算出加密用的密钥。如 RSA, Diffie-Hellman(DH),Elliptic Curve cryptography(ECC)。 RSA 应用超广泛,由于关于 RSA 的各种文章非常多,就不详细解释了。要注意的是一些遗留系统还在使用 128 位私钥,是非常危险的,至少 1024 以上才能保证加密数据的安全。 PKey 模块包含各种 public / private key 算法,RSA 的使用示例: require "openssl" rsa = OpenSSL::PKey::RSA # RSA 公钥和密钥, 为 RSA 的实例 # pem 格式 base64 的内容 password = 'you shall not pass' # 生成 pem 格式的私钥,参照 openssl 命令的用法 private_key = rsa.new(2048).to_pem des3, password # 如果不给 password 参数,会要求在命令行中输入密码 public_key = rsa.new(private_key, password).public_key # 注意 source 长度不能大于 key 的字节数 - 2 source = 'hello world' crypted = rsa.new(public_key).public_encrypt source decrypted = rsa.new(private_key, password).private_decrypt crypted puts decrypted #=> hello world 非对称加密算法的运算量比较大,如果要对大文件进行加密,一般全文使用对称加密算法加密,只对(对称加密算法的键)使用非对称加密。这种简单组合就不演示了 …… 椭圆曲线加密算法 椭圆曲线加密算法也是一种单向加密算法,简单的说为什么 nb,就是:要实现相同的加密强度,椭圆曲线族比 RSA 需要的密钥长度小很多。 openssl 从 0.9.8 起,加入了各种椭圆函数曲线签名算法,还有 前-Sun公司 贡献的 ECDH (椭圆函数 key 到 Diffie-Hellman key 的转换)。 查看内建的椭圆曲线: require "openssl" puts OpenSSL::PKey::EC.builtin_curves.map{|x|x.join "\t"} secp112r1 SECG/WTLS curve over a 112 bit prime field secp112r2 SECG curve over a 112 bit prime field secp128r1 SECG curve over a 128 bit prime field secp128r2 SECG curve over a 128 bit prime field secp160k1 SECG curve over a 160 bit prime field secp160r1 SECG curve over a 160 bit prime field secp160r2 SECG/WTLS curve over a 160 bit prime field secp192k1 SECG curve over a 192 bit prime field secp224k1 SECG curve over a 224 bit prime field secp224r1 NIST/SECG curve over a 224 bit prime field secp256k1 SECG curve over a 256 bit prime field secp384r1 NIST/SECG curve over a 384 bit prime field secp521r1 NIST/SECG curve over a 521 bit prime field prime192v1 NIST/X9.62/SECG curve over a 192 bit prime field prime192v2 X9.62 curve over a 192 bit prime field prime192v3 X9.62 curve over a 192 bit prime field prime239v1 X9.62 curve over a 239 bit prime field prime239v2 X9.62 curve over a 239 bit prime field prime239v3 X9.62 curve over a 239 bit prime field prime256v1 X9.62/SECG curve over a 256 bit prime field sect113r1 SECG curve over a 113 bit binary field sect113r2 SECG curve over a 113 bit binary field sect131r1 SECG/WTLS curve over a 131 bit binary field sect131r2 SECG curve over a 131 bit binary field sect163k1 NIST/SECG/WTLS curve over a 163 bit binary field sect163r1 SECG curve over a 163 bit binary field sect163r2 NIST/SECG curve over a 163 bit binary field sect193r1 SECG curve over a 193 bit binary field sect193r2 SECG curve over a 193 bit binary field sect233k1 NIST/SECG/WTLS curve over a 233 bit binary field sect233r1 NIST/SECG/WTLS curve over a 233 bit binary field sect239k1 SECG curve over a 239 bit binary field sect283k1 NIST/SECG curve over a 283 bit binary field sect283r1 NIST/SECG curve over a 283 bit binary field sect409k1 NIST/SECG curve over a 409 bit binary field sect409r1 NIST/SECG curve over a 409 bit binary field sect571k1 NIST/SECG curve over a 571 bit binary field sect571r1 NIST/SECG curve over a 571 bit binary field c2pnb163v1 X9.62 curve over a 163 bit binary field c2pnb163v2 X9.62 curve over a 163 bit binary field c2pnb163v3 X9.62 curve over a 163 bit binary field c2pnb176v1 X9.62 curve over a 176 bit binary field c2tnb191v1 X9.62 curve over a 191 bit binary field c2tnb191v2 X9.62 curve over a 191 bit binary field c2tnb191v3 X9.62 curve over a 191 bit binary field c2pnb208w1 X9.62 curve over a 208 bit binary field c2tnb239v1 X9.62 curve over a 239 bit binary field c2tnb239v2 X9.62 curve over a 239 bit binary field c2tnb239v3 X9.62 curve over a 239 bit binary field c2pnb272w1 X9.62 curve over a 272 bit binary field c2pnb304w1 X9.62 curve over a 304 bit binary field c2tnb359v1 X9.62 curve over a 359 bit binary field c2pnb368w1 X9.62 curve over a 368 bit binary field c2tnb431r1 X9.62 curve over a 431 bit binary field wap-wsg-idm-ecid-wtls1 WTLS curve over a 113 bit binary field wap-wsg-idm-ecid-wtls3 NIST/SECG/WTLS curve over a 163 bit binary field wap-wsg-idm-ecid-wtls4 SECG curve over a 113 bit binary field wap-wsg-idm-ecid-wtls5 X9.62 curve over a 163 bit binary field wap-wsg-idm-ecid-wtls6 SECG/WTLS curve over a 112 bit prime field wap-wsg-idm-ecid-wtls7 SECG/WTLS curve over a 160 bit prime field wap-wsg-idm-ecid-wtls8 WTLS curve over a 112 bit prime field wap-wsg-idm-ecid-wtls9 WTLS curve over a 160 bit prime field wap-wsg-idm-ecid-wtls10 NIST/SECG/WTLS curve over a 233 bit binary field wap-wsg-idm-ecid-wtls11 NIST/SECG/WTLS curve over a 233 bit binary field wap-wsg-idm-ecid-wtls12 WTLS curvs over a 224 bit prime field Oakley-EC2N-3 IPSec/IKE/Oakley curve #3 over a 155 bit binary field. Not suitable for ECDSA. Questionable extension field! Oakley-EC2N-4 IPSec/IKE/Oakley curve #4 over a 185 bit binary field. Not suitable for ECDSA. Questionable extension field! 下面是结合 ECC 和 DSA 的电子签名示例: #! /bin/env ruby # coding: utf-8 require "openssl" require "digest/sha2" # 要检验的 digest message msg1 = Digest::SHA384.digest 'hello world' msg2 = Digest::SHA384.digest 'goodbye world' # 初始化参数为曲线名, 查看所有曲线: ec.builtin_curves skey = OpenSSL::PKey::EC.new("c2tnb359v1").generate_key puts "\bthe private key pem:", skey.to_pem # 用 private key 签名 sign = skey.dsa_sign_asn1 msg1 # 将 private key 消除后,to_pem 就只打印 public key 了 skey.private_key = nil public_pem = skey.to_pem # to_bn means "to big number" puts "\nthe public key number:", skey.public_key.to_bn puts "\nthe public key pem:", public_pem vkey = OpenSSL::PKey::EC.new public_pem # 用 public key 检验 puts "\nverify:" puts(vkey.dsa_verify_asn1 msg1, sign) # true puts(vkey.dsa_verify_asn1 msg2, sign) # false ------------------------------------------------------- 参考 SSL and TLS: http://horms.net/projects/ssl_and_tls/stuff/ssl_and_tls.pdf 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-11-02
不错的简介
为啥不发到综合版? |
|
返回顶楼 | |
发表时间:2010-11-02
Spike 写道 不错的简介
为啥不发到综合版? 这主要是介绍 Ruby 中如何算摘要和加密 …… 几乎不涉及各种算法的背景 |
|
返回顶楼 | |
发表时间:2010-11-02
误解的原因是经常站点对密码做MD5处理....,所以很多人都认为是加密.
加密通常是要伴随着信息还原的,即揭秘过程。 ruby ms也没提供啥算法,基本都是openssl在唱戏。。 |
|
返回顶楼 | |
发表时间:2010-11-03
http://coolshell.cn/wp-content/uploads/2010/10/rijndael_ingles2004.swf
看这个 |
|
返回顶楼 | |
发表时间:2010-11-03
最后修改:2010-11-03
CharlesCui 写道 http://coolshell.cn/wp-content/uploads/2010/10/rijndael_ingles2004.swf
看这个 就是这个 flash 害我算错了 mix columns …… 弄了很久才发现改正 那个是 GF(2^8) 上的乘法,不是整数乘法 > < 还有 RCON 部分有点错误,不是 RCON(4), RCON(8) ... 而是 RCON(1), RCON(2) ... |
|
返回顶楼 | |