RSA 之padding
参考: openssl之 : crypto/rsa/rsa_pk1.c
对于 RSA_PKCS1_PADDING 来讲(参看: ./crypto/rsa/rsa_eay.c ):
- 私钥加密时,使用的是: RSA_padding_add_PKCS1_type_1(…) pad的是定值 0xff
- 公钥加密时,使用的是: RSA_padding_add_PKCS1_type_2(…) pad的是随机的非零值 (这也是为什么公钥加密每次结果不同,而私钥加密每次结果相同的原因;对于私钥加密,多半用于签名,不需要随机,或者说,相同的数据每次签名结果都相同是很好的)
Optimal Asymmetric Encryption Padding (OAEP)
OAE: 即: 最完美的非对称加密; 而OAEP 是一种padding ; 参考: http://en.wikipedia.org/wiki/Optimal_asymmetric_encryption_padding
其他padding:
参考资料:
rsa算法: http://www.di-mgt.com.au/rsa_alg.html
http://www.douban.com/note/338531480/
http://www.tuicool.com/articles/aMfIba
http://crypto.stackexchange.com/questions/22531/how-does-rsa-padding-work-exactly
PKCS #1: RSA Cryptography Specifications Version 2.0
Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography Specifications Version 2.1
PSS: (具体实现参看 : pss.go)
- Probabilistic Signature Scheme, a secure way of creating signatures with RSA (see also: PKCS1#Schemes)
MGF(pss 的时候需要):
- Mask Generation Function, a function generating an arbitrary number of bits for a given input. (for example MGF1 from PKCS1)
golang flag package
对于 bool选项,需要使用 ‘=’指定,否则无效,如: cmd -b=false 而不能 cmd -b false
PHP soap错误: “Error Fetching http headers”
缘起
PHP的soap使用有相当的时间了,今天随手给系统添加了个功能,通过soap实现的,却出现错误:”Error Fetching http headers”
分析
一般来讲,soap的错误可以先用tcpdump抓包看看请求响应是否正常,于是,抓包观察了一下,没有发现异常;但为什么会出现这种错误呢?百思不得姐。
应该是soapclient中抛出的错误,看看错误处的逻辑吧,翻开源码看了一下,也没有发现异常。
突然灵感就来了,大概是执行时间长所致,其实也不算长,大概5s吧!看了一下soap中关于请求响应超时的设置方式(通过default_socket_timeout 来设置),我才发现这太机器的default_socket_timeout 为 4 ; 修改大一些后,问题解决
Memcached 学习
缘起
Memcached的性能是否还能提高?Memcached还能做哪些方面的优化?Memcached的UDP性能能比TCP好多少?
分析
此前,每个线程都使用相同的fd,会不会产生争用的问题?
通过ssh实现socket代理
copy from: http://blog.csdn.net/xanxus46/article/details/38942215
ssh是用来远程登录主机的作用大家都知道,而且传输的内容全部经过加密处理也是大家喜欢其的主要因素。但其实ssh能做的更多,例如作为代理服务器。
通过ssh 的-D参数,我们可以在本地搭建一个socks5服务器,具体使用方法如下:
ssh -qTNf -D 127.0.0.1:12345 test@222.333.444.555
其中-q表示该命令进入安静模式
-T是指该命令不占用shell
-N是指该命令不执行远程命令
-f是指该命令在后台运行
-D是该命令重要参数,他的后面跟着socks5服务器的地址与端口
最后就是远程服务器用户名和地址
执行完该命令后,我们需要在浏览器中设置代理服务器,地址和端口就是上面提到的,然后记得选择socks5协议。那么以后每浏览一个页面,都会先经过代理服务器,然后再去请求页面,接着页面先到达代理服务器,最后才返回我们自己的浏览器。过程好像变得复杂了,但是这样的作用是什么呢,很常见,例如有一些校园网是限制ipv4流量的,如果我们找到一台支持ipv6的远程服务器,而且校园网大部分都支持ipv6,那么我们就能通过建立ipv6代理服务器来无流量限制上网了。再者,如果我们能找到外国的免费服务器,能让我们通过ssh登录,那么我们通过建立代理服务器来翻墙了,翻墙后能做的事情就请读者自行脑补吧
。
接下来继续讲的是ssh的端口映射功能,这个也相当好用,例如我们在家如果想访问公司或学校的资源,我们需要先登录一台拥有公网ip的服务器,然后在访问局域网的主机,譬如,我们是A主机,需要访问学校的C主机,而只有学校B主机有公网ip,我们需要先登录B主机,然后才能访问C主机。过程很麻烦,这时我们就需要做一个端口映射了,而这个ssh也能帮我们完成。具体命令如下:
ssh -N -f -L 127.0.0.1:12345:10.21.0.34:22 test@12.3..4.5
其中-N,-f作用上面已经讲了,这里最重要的是-L命令,它作用是做本地映射,使得远程服务器的端口相当于本地某自定义的端口,如上面的命令,本地的12345端口就相当于10.21.0.34的22端口,以后我只需要使用ssh user@127.0.0.1 -p 12345命令就能登录10.21.0.34了,注意user是10.21.0.34的用户,最后就是我们所使用的中间服务器,这个地址需要是我们直接访问到的。其实上面所说的A主机就是127.0.0.1,B主机就是12.3.4.5,C主机就是10.21.0.34。当然了,有本地映射肯定有远程映射,就是把-L换成-R,这样我们访问远程主机的端口就相当于访问本地的端口,但我没发现该功能的更多用途。
如果你没有什么中间服务器,只是想做个端口映射,那也很简单,如下:
ssh -N -f -L 12345:12.3.4.5:22 test@12.3.4.5
就是把远程服务器地址写成中间服务器地址就完事了。
学习完ssh这些用法后有没有对ssh产生无比崇敬的心情的,各种膜拜啊。
关于socket代理 : http://blog.csdn.net/cuiyifang/article/details/8784394
端口扫描工具
缘起
长城宽带为用户提供了公网IP,但是没有允许进入的连接,想提供管理内网的服务就很难。
真的没有允许任何一个端口的进入吗?
使用nmap工具扫描看看: http://nmap.org/
基本命令:
1 nmap -p 1-65535 -P0 your_ip
近期学习总结
2014年11月21号 晴
大约从7、8月份开始,我对Go产生了兴趣,并试图用Go写一个sessionserver;9月24号,我有了儿子,鲜有时间学习,但是,我还是在伺候月子的起见熬夜完成了sessionserver的原型,测试结果基本满意。
但是,由于业务的需要,我需要写一个lua版本的sdk,于是,我的精力一下转移到了lua,由于先前对lua有所了解,所以写起来不太费劲;但是在 ffi 上还是浪费了不少的时间,大约1周的时间完成业务逻辑,使用ffi 做加密解密算法上浪费了大约2周的时间。
不管如何,我还是学到了一些东西的;此前,我不太愿意学习太多的语言,只愿精通几个足矣,通过对Go和lua的学习,让我对语言产生了兴趣,我希望能有时间学习更多的语言;不同的语言有不同的思想,不同的语言有不同的用途。
下个阶段:
- 主要精力放在Go上,做出一些成绩
- 大约20%的精力去学习其他的语言
Lua-5.2-Reference-Manual-ZH_CN
lua ffi.string 之殇
缘起
使用ffi给lua包一个rsa算法, 刚刚学习ffi,连文档都没仔细看过,当返回加密结果时,如果直接返回CDATA,则解密没有问题,如果转为lua string(使用ffi.string) ,则后续无法解密
调试
- 直接在lua中调试基本无法凑效
- 重新编译openssl的libcrypt库,加入调试信息,先是祭出gdb,调的晕乎乎的;然后,则可以地方修改C代码,打印调试信息
- 发现,使用ffi.string 和不使用ffi.string 的差别在于,字符串的前面一部分是相同的,后面一部分是不同的,出于对零字节的敏感,发现是从零字节之后开始不同的;猜测ffi.string()或许可以有第二个参数(悲催,因为给一个参数也好使过,所以再没看过文档)
- 查ffi的文档,发现ffi.string()是有第二个参数的,添加第二个参数,问题解决
- 这个花费了我大约2天的时间,欲哭无泪
结论
- ffi.string(cdata, len) 是有第二个参数的,如果不写第二个参数,则从第一个零字节处截断
- 学习要循序渐进,文档是要看的
成果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
local ffi = require("ffi") local Rsa = ffi.load("crypto") ffi.cdef[[ typedef struct rsa_st RSA; typedef struct bio_st BIO; typedef int pem_password_cb(char *buf, int size, int rwflag, void *userdata); int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa,int padding); int RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa,int padding); int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa,int padding); int RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa,int padding); BIO *BIO_new_mem_buf(void *buf, int len); RSA *PEM_read_bio_RSA_PUBKEY(BIO *bp, RSA **x, pem_password_cb *cb, void *u); RSA *PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **x, pem_password_cb *cb, void *u); int RSA_size(const RSA *r); ]] local RSA_PKCS1_PADDING = 1; local function init_public_key(pem_key) local bio = Rsa.BIO_new_mem_buf(ffi.cast("unsigned char *", pem_key), -1) local rsa = Rsa.PEM_read_bio_RSA_PUBKEY(bio, nil, nil, nil); if rsa == nil then return nil, "parse public key fail" end return rsa, nil end local function init_private_key(pem_key) local bio = Rsa.BIO_new_mem_buf(ffi.cast("unsigned char *", pem_key), -1) local rsa = Rsa.PEM_read_bio_RSAPrivateKey(bio, nil, nil, nil); if rsa == nil then return nil, "parse public key fail" end return rsa, nil end local function public_decrypt(key, data) local rsa, err = init_public_key(key) if err ~= nil then return nil, err end local size = tonumber(Rsa.RSA_size(rsa)) local decrypted = ffi.new("unsigned char[?]", size) data = ffi.cast("const unsigned char *" ,data) print("string len"..string.len(ffi.string(data))) local len = Rsa.RSA_public_decrypt(size, data, decrypted, rsa, RSA_PKCS1_PADDING) return ffi.string(decrypted, len),len end local function private_encrypt(key, data) local rsa, err = init_private_key(key) if err ~= nil then return nil, err end local size = tonumber(Rsa.RSA_size(rsa)) local encrypted = ffi.new("unsigned char[?]", size) local len = Rsa.RSA_private_encrypt(#data, data, encrypted, rsa, RSA_PKCS1_PADDING) return ffi.string(encrypted, len),len end |