Movies-Server Protocols
目录
重要更新:此处不再更新,点此查看最新版文档!
加密解密算法
采用AES加密算法/CBC模式/PKCS5Padding补全
密钥:????????????
向量: byte[16],由调用方随机生成
Get请求:
将16位(byte[16])的向量(iv)置于二进制密文头部,再进行base64encode,生成最终的s参数
Post请求:
将16位(byte[16])的向量(iv)置于二进制密文头部,再进行base64encode,最后发送二进制流。
PKCS5Padding规则
1、计算输入长度为L。
2、如果L是16倍数,padding长度为16,padding值为0x10。即在输入后面补齐16字节的0x10。
3、如果L不是16倍数,padding长度为16-L%16,padding值为16-L%16。即在输入后面补齐16-L%16的字节,值为16-L%16。
2和3其实可以根据公式 16-L%16 写成一条规则,这里只是强调2的特殊性,明确并不是不做补齐。
参考:http://www.xjump.me/content.htm?id=72
测试用例
接口:http://movies.chenjiehua.me/
原始参数:
token=60035ef9e144c8662591914b219a252d0c93854e
rt=1490000000
加密后生成s参数:
s=XGobIjyl8T4zuiPr+LMGjw07BSBKDC1ecA5PLjmHmUsrR9BhelPl9bmPU40agn6xu4SaCZ2j/jop2LjrAza9NV5F7VoRbeumjRqHxNgL8z4=
GET请求链接:
返回结果:
{ "c": 0, "d": { "rt": "1490000000", "token": "60035ef9e144c8662591914b219a252d0c93854e", "type": "get" } }
POST请求链接:http://movies.chenjiehua.me/test
Request Body:XGobIjyl8T4zuiPr+LMGjw07BSBKDC1ecA5PLjmHmUsrR9BhelPl9bmPU40agn6xu4SaCZ2j/jop2LjrAza9NV5F7VoRbeumjRqHxNgL8z4=
返回结果:
{ "c": 0, "d": { "rt": "1490000000", "token": "60035ef9e144c8662591914b219a252d0c93854e", "type": "post" } }
其他返回代码说明:http://chenjiehua.me/?p=507
代码示例:
Python
import base64 from Crypto import Random from Crypto.Cipher import AES class AESCipher: """ AES 加密解密 """ def __init__(self, key): self.bs = 16 if len(key) >= 16: self.key = key[:16] else: self.key = self._pad(key) def encrypt(self, raw): raw = self._pad(raw) iv = Random.new().read(AES.block_size) cipher = AES.new(self.key, AES.MODE_CBC, iv) return base64.b64encode(iv + cipher.encrypt(raw)) def decrypt(self, enc): enc = base64.b64decode(enc) iv = enc[:AES.block_size] cipher = AES.new(self.key, AES.MODE_CBC, iv) return self._unpad(cipher.decrypt(enc[AES.block_size:])) def _pad(self, s): return s + (self.bs - len(s) % self.bs) * chr(self.bs - len(s) % self.bs) def _unpad(self, s): return s[:-ord(s[len(s) - 1:])]
参考:https://gist.github.com/crmccreary/5610068
Android
private static String encryptParamsToGet(byte[] PSW, Map<String, String> params) throws Throwable { byte[] buff = encryptParamsToPost(PSW, params); if (buff == null) { return null; } return Base64.encodeToString(buff, Base64.DEFAULT); } private static byte[] encryptParamsToPost(byte[] PSW, Map<String, String> params) throws Throwable { if (params == null) { return null; } StringBuilder sb = new StringBuilder(); Iterator<Map.Entry<String, String>> iter = params.entrySet().iterator(); while (iter.hasNext()) { Map.Entry<String, String> entry = iter.next(); String key = entry.getKey(); String value = entry.getValue(); if (sb.length() > 0) { sb.append('&'); } sb.append(key).append('=').append(Uri.encode(value)); } byte[] buff = sb.toString().getBytes("UTF-8"); byte[] iv = new byte[16]; Random rd = new Random(); rd.nextBytes(iv); byte[] data = Aes.encrypt(buff, PSW, iv); ByteArrayOutputStream baos = new ByteArrayOutputStream(); baos.write(iv, 0, iv.length); baos.write(data, 0, data.length); byte[] out = baos.toByteArray(); try { baos.close(); } catch (Throwable e) { } return out; }
iOS
需要NSData+AESCrypt、NSData+CommonCrypto.h
#import "Encryptor.h" #import "NSData+CommonCrypto.h" #import "NSData+AESCrypt.h" static char kRandomCharTable[62] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; static NSString *kEncryptKey = @"AjGfpbbQmU7EAnkJ"; @implementation Encryptor + (NSData *)AESEncrytAsData:(NSDictionary *)params { NSMutableString *str = [NSMutableString new]; for (NSString *key in params) { NSString *value = params[key]; NSString *vString = [value stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; [str appendFormat:@"&%@=%@", key, vString]; } NSString *line = @""; if ([str length] > 0) { line = [str substringFromIndex:1]; } NSData *data = [line dataUsingEncoding:NSUTF8StringEncoding]; NSData *iv = [self randomDataOfLength:16]; CCCryptorStatus status = kCCSuccess; NSData *encrypted = [data dataEncryptedUsingAlgorithm:kCCAlgorithmAES128 key:kEncryptKey initializationVector:iv options:kCCOptionPKCS7Padding error:&status]; NSMutableData *result = [[NSMutableData alloc] initWithData:iv]; [result appendData:encrypted]; return result; } + (NSString *)AESEncryptAsBase64:(NSDictionary *)params { NSData *d = [self AESEncrytAsData:params]; return [d base64Encoding]; } + (NSData *)randomDataOfLength:(NSInteger)length { char rand_chars[length]; for (int i = 0; i < length; i++) { u_int32_t randChar = arc4random() % 62; rand_chars[i] = kRandomCharTable[randChar]; } return [NSData dataWithBytes:rand_chars length:length]; } @end
评论