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

评论