早期造个对象,写了个php的rsa帮助类库,先看使用方法

$keys = RsaHelper::new_rsa_key();
//生成完key之后应该记录下key值,这里省略
$privkey = $keys['privkey'];
$pubkey  = $keys['pubkey'];
/* $privkey = '-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKX0cHYmXyHhIx5/
k6GMneVKpUDsqP2PdKFGollWYCbxJUAHPsHsjILGI0ucGnC+VpfKVX6DEagoRBZv
tz+nnpcreVPtNbKMNzhukSY3Mt7Fo1rMaj0pbsaMom1noQjsKJlVgz6akP7RMm4W
zpnMvcDq/9PucfCQP1FGZTbg1hUxAgMBAAECgYBeGam/ROjChC9utrZWby6E+nuT
wd3c0QA4Bp49+/1Pd4NAuBr8yQ2vhXwz/lL7xOHC9ibeMqHLcPGSq0wEGx6P/XWM
0Ldpwu6cWv4qOdHdBDdqrO6mkyBljt4sq1WtTnkLgZ0cCTTeVnnFDmlc9Zr9oT5k
UezOEb55GziRD5XUxQJBANLx3kUjOFRyR1I/wZYHHJkcm8pSgpDe4b1G60orZa9J
nbUTM+cIvmNKzm99m9aIMvgjk/LBydpxV7W5YYDxHrcCQQDJZpcu5OPWNJ3TdrrK
KNa1lfUo5Vb0sCgpTueZdwngBr043XRTyJHqjziX/9Z19UWrE9Gz6U1Klpa7SBYo
O4NXAkEArsKRCahXJ6cRrXOClx/HMpY//0uCPjFYxa32ipkPgjwz+uswycw1px83
jah7ri1iRK99B9ZCu8XBC53MyL16WwJAISu+dsDILb2YyP1jImy7gEjkignL2p0w
4CzYxFPw0m8Jt1XyFOKR9doE7jP69I6jHNw0y7b/Peuzg8EJtTKoHQJBAITAjM7Q
QnIEgYHvw3gaQI8/6992Y0DSMaHt50peI6uJoMV+X9IcjY1eFUSOHV8nb0uI8xQ7
4SbU2yvLPTqUk50=
-----END PRIVATE KEY-----';
$pubkey = '-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCl9HB2Jl8h4SMef5OhjJ3lSqVA
7Kj9j3ShRqJZVmAm8SVABz7B7IyCxiNLnBpwvlaXylV+gxGoKEQWb7c/p56XK3lT
7TWyjDc4bpEmNzLexaNazGo9KW7GjKJtZ6EI7CiZVYM+mpD+0TJuFs6ZzL3A6v/T
7nHwkD9RRmU24NYVMQIDAQAB
-----END PUBLIC KEY-----'; */
//初始化rsaobject
RsaHelper::init($privkey, $pubkey);
//原文
$data = 'hello';
//私钥加密示例
$encode = RsaHelper::priv_encode($data);
$ret = RsaHelper::pub_decode($encode);
var_dump($ret);
//公钥加密示例
$encode = RsaHelper::pub_encode($data);
$ret = RsaHelper::priv_decode($encode);
var_dump($ret);

      类库源码如下

class RsaHelper{
    private static $_privkey = '';
    private static $_pubkey = '';
    private static $_isbase64 = false;
    /**
     * 初始化key值
     * @param  string  $privkey  私钥
     * @param  string  $pubkey   公钥
     * @param  boolean $isbase64 是否base64编码
     * @return null
     */
    public static function init($privkey, $pubkey, $isbase64=false){
        self::$_privkey = $privkey;
        self::$_pubkey = $pubkey;
        self::$_isbase64 = $isbase64;
    }
    /**
     * 私钥加密
     * @param  string $data 原文
     * @return string       密文
     */
    public static function priv_encode($data){
        $outval = '';
        $res = openssl_pkey_get_private(self::$_privkey);
        openssl_private_encrypt($data, $outval, $res);
        if(self::$_isbase64){
            $outval = base64_encode($outval);
        }
        return $outval;
    }
    /**
     * 公钥解密
     * @param  string $data 密文
     * @return string       原文
     */
    public static function pub_decode($data){
        $outval = '';
        if(self::$_isbase64){
            $data = base64_decode($data);
        }
        $res = openssl_pkey_get_public(self::$_pubkey);
        openssl_public_decrypt($data, $outval, $res);
        return $outval;
    }
    /**
     * 公钥加密
     * @param  string $data 原文
     * @return string       密文
     */
    public static function pub_encode($data){
        $outval = '';
        $res = openssl_pkey_get_public(self::$_pubkey);
        openssl_public_encrypt($data, $outval, $res);
        if(self::$_isbase64){
            $outval = base64_encode($outval);
        }
        return $outval;
    }
    /**
     * 私钥解密
     * @param  string $data 密文
     * @return string       原文
     */
    public static function priv_decode($data){
        $outval = '';
        if(self::$_isbase64){
            $data = base64_decode($data);
        }
        $res = openssl_pkey_get_private(self::$_privkey);
        openssl_private_decrypt($data, $outval, $res);
        return $outval;
    }
    /**
     * 创建一组公钥私钥
     * @return array 公钥私钥数组
     */
    public static function new_rsa_key(){
        $res = openssl_pkey_new();
        openssl_pkey_export($res, $privkey);
        $d= openssl_pkey_get_details($res);
        $pubkey = $d['key'];
        return array(
            'privkey' => $privkey,
            'pubkey'  => $pubkey
        );
    }
}

      妈蛋,win平台下的php protobuf折腾死我了,又改成py了,所以,python版的rsa加密辅助类来了

def new_keys():
    (bob_pub, bob_priv) = rsa.newkeys(1024)
    return {'pubkey':bob_pub.save_pkcs1(), 'privkey':bob_priv.save_pkcs1()}
class RsaHelper:
    def __init__(self, privkey, pubkey):
        self._privkey = privkey.decode('string-escape')
        self._pubkey = pubkey.decode('string-escape')
    def encode_priv(self, data):
        privkey = rsa.PrivateKey.load_pkcs1(self._privkey)
        crypto = rsa.encrypt(data, privkey)
        return crypto
    def decode_pub(self, data):
        pubkey = rsa.PublicKey.load_pkcs1(self._pubkey)
        msg = rsa.decrypt(data, pubkey)
        return msg
    def decode_priv(self, data):
        privkey = rsa.PrivateKey.load_pkcs1(self._privkey)
        msg = rsa.decrypt(data, privkey)
        return msg
    def encode_pub(self, data):
        pubkey = rsa.PublicKey.load_pkcs1(self._pubkey)
        crypto = rsa.encrypt(data, pubkey)
        return crypto

      本来还以为挺有成就感了,结果,奶奶,竟然有个pkcs7规范,使用 PyCrypto 进行 AES/ECB/PKCS#5(7) 加密

import struct, zlib, StringIO
from Crypto.Cipher import AES
def zip_data(data):
    '''压缩数据的方法'''
    return zlib.compress(data)
def unzip_data(data):
    '''解压缩数据'''
    return zlib.decompress(data)
def pkcs7_padding(s):
    BS = AES.block_size
    return s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
def pkcs7_unpadding(s):
    return s[0:-ord(s[-1])]
def aes_encrypt(text, key, mode=AES.MODE_CBC):
    '''AES加密算法'''
    cryptor = AES.new(key, mode, key)
    #这里密钥key 长度必须为16(AES-128)
    text = pkcs7_padding(text)
    ciphertext = cryptor.encrypt(text)
    return ciphertext
def aes_decrypt(text, key, mode=AES.MODE_CBC):
    '''AES解密算法'''
    cryptor = AES.new(key, mode, key)
    plain_text  = cryptor.decrypt(text)
    plain_text = pkcs7_unpadding(plain_text)
    return plain_text

================更新于2014-11-24 13:00===================
      在测试python的AES加密时候发现网上的一个算法有缺陷,由于AES要求加密的字符串为16的倍数,所以不足需要不足长度,那么来看网上的算法

def aes_encrypt(text, key, mode=AES.MODE_CBC):
    PADDING = '\0' #不足填充空
    cryptor = AES.new(key, mode, b'0000000000000000')
    #这里密钥key 长度必须为16(AES-128)
    length = 16
    count = len(text)
    if count < length:
        add = (length-count)
        #\0 backspace
        text = text + (PADDING * add)
    elif count > length:
        add = (length-(count % length))
        text = text + (PADDING * add)
    ciphertext = cryptor.encrypt(text)
    return ciphertext
def aes_decrypt(text, key, mode=AES.MODE_CBC):
    PADDING = '{'
    cryptor = AES.new(key, mode, b'0000000000000000')
    plain_text  = cryptor.decrypt(text)
    return plain_text.rstrip(PADDING)

      粗看没有问题,但内容先gzip后,再做aes解密,gzip后的\0会被去掉,结果导致ungzip失败,真是个悲剧。再来看这位博主用”{“来填充: Creating 128 bit AES Ciphertext and Key with Python PyCrypto,但是要是{也冲突如何是好呢,那么解决方法来了:Python Encrypting with PyCrypto AES。解决方法为在内容结尾填充文本长度,代码如下:

def aes_encrypt(text, key, mode=AES.MODE_CBC):
    cryptor = AES.new(key, mode, b'0000000000000000')
    #这里密钥key 长度必须为16(AES-128)
    length = 16
    count = len(text)
    lengx = length - (count % length)
    text += chr(count)*lengx
    ciphertext = cryptor.encrypt(text)
    return ciphertext
def aes_decrypt(text, key, mode=AES.MODE_CBC):
    cryptor = AES.new(key, mode, b'0000000000000000')
    plain_text  = cryptor.decrypt(text)
    return plain_text[:-ord(plain_text[-1])]

      当然代码还是有问题,chr只能支持0-255,那么解决方法可以根据需要定义结尾为比如最后4个字节为文本长度,那么代码如下:

def aes_encrypt(text, key, mode=AES.MODE_CBC):
    cryptor = AES.new(key, mode, b'0000000000000000')
    #这里密钥key 长度必须为16(AES-128)
    length = 16
    count = len(text)
    lengx = length - (count % length)
    countbin = struct.pack('>L', count) #四个字节的int
    intlen = len(countbin)
    padding = ''
    if lengxL', plain_text[-4:])[0]
    return plain_text[:dlen]

测试方法如下:

def test_aes():
    seckey = 'asdf'*4
    text = 'testasdsdfdsdfsd1'*200
    atxt = aes_encrypt(text, seckey)
    text = aes_decrypt(atxt, seckey)
    print text

       python压缩和解压缩的方法,解压缩很容易找到,压缩的方法可以参考这里:http://stackoverflow.com/questions/8506897/how-do-i-gzip-compress-a-string-in-python

def gzip_data(data):
    '''压缩数据的方法'''
    buf = StringIO.StringIO()
    f = gzip.GzipFile(fileobj=buf, mode="w")
    f.write(data)
    f.close()
    return buf.getvalue()
def ungzip_data(data):
    '''解压缩数据'''
    buf = StringIO.StringIO(data)
    f = gzip.GzipFile(fileobj=buf)
    return f.read()
def test_gzip():
    '''测试'''
    istr = 'asdfasd'
    gdata  = gzip_data(istr)
    print ungzip_data(gdata)

      第一次测试的时候出现错误:
File "D:\Python26\lib\gzip.py", line 212, in read
self._read(readsize)
File "D:\Python26\lib\gzip.py", line 267, in _read
self._read_eof()
File "D:\Python26\lib\gzip.py", line 304, in _read_eof
hex(self.crc)))
IOError: CRC check failed 0x28d60008 != 0x0L

是因为在gzip_data中write后没有close掉,看官方文档如下:Calling a GzipFile object’s close() method does not close fileobj, since you might wish to append more material after the compressed data. This also allows you to pass a StringIO object opened for writing as fileobj, and retrieve the resulting memory buffer using the StringIO object’s getvalue() method.

07 / 11 / 2014 buling

      港行iphone6预定有很多规则限制:1、每个apple id限抢一次;2、每个手机号码限抢一次;每个身份证限抢一次。第一次预定成功,结果通行证过期,只能放弃,之后又买了一张卡,连续早起N次都没有结果,昨天又买了一张卡,今天早上再次失败,痛定思痛,从脚本开始,跟黄牛比手工不靠谱。目前港行价格16G基本还是5000RMB左右,所以脚本来了

var storeNum = 'R428',            //ifc店
    modelNum = 'MG4H2ZP/A',  //银色64G
    govType  = 'entryExitPass',  //通行证
    govID    = 'C050XXXXX';      //证ID
//这里用于去除可用性检测
if(!window._fetchPostData){
    _fetchPostData = fetchPostData
    fetchPostData = function(eventId, params, callback){
       if(eventId=='availability'){
           return false;
       }
       _fetchPostData(eventId, params, callback);
    }
}
//选择店面
$('#productSelection [name=selectedStoreNumber]').val(storeNum ).change();
//选择iphone6
$('#product .box').eq(0).click();
$('#locked .box').eq(0).click();
//选择颜色,第一个银色
$('#color input.iPhone6').eq(0).parent().click();
//选择64G
$('#model').removeClass('disabled');
$('#model .loading-spinner').addClass('hidden');
$('#model .group').attr('style', '').find('input[value="'+modelNum+'"]').parent().click().parent().show();
//填写联系资料
$('#quantity [name="selectedQuantity"]').val(2);
$('#contact [name="selectedGovtIdType"]').val(govType);
$('#contact [name="govtId"]').val(govID);
//选择时间
$('.button-container a, #time').removeClass('disabled');
$('#time select option').eq(2).prop('selected', true);
//提交
$('#productSelection')[0].submit();

      如果预定成功,我再来更新成自动化脚本,如果没成功就算了,来,嘿、嘿、嘿,加油!