代理的加密部分
就是怎么在 PHP/mcrypt 和 PyCrypto 之间 DES(或其他加密算法,比如3DES/RSA/..) 通信的问题,我这里还额外考察了下 .NET 平台的算法
网上询问相关问题的还挺多,尤其是 PHP 和 .NET 之间的 DES 转换。主要是 PHP/mcrypt 隐藏了 padding 的细节,且只保留了 ZERO_PADDING 模式,所以不明白cyrpto原理的不太容易找到症结所在。我的传输方案统一用 pkcs#7 padding.
首先是给服务器端增加的 PKCS#7 PADDING 函数,来自PHP官方函数手册上某人的注释
{
$block = mcrypt_get_block_size($crypto, $mode);
$len = strlen($dat);
$padding = $block - ($len % $block);
$dat .= str_repeat(chr($padding),$padding);
return $dat;
}
function strip_pkcs7($crypto, $mode, $text)
{
$block = mcrypt_get_block_size($crypto, $mode);
$packing = ord($text{strlen($text) - 1});
if($packing and ($packing < $block)){
for($P = strlen($text) - 1; $P >= strlen($text) - $packing; $P--){
if(ord($text{$P}) != $packing){
$packing = 0;
}
}
}
return substr($text,0,strlen($text) - $packing);
}
本地端 .NET 平台的 descrypto 封装
# ipcrypto.py
from System import Array, Byte
from System.Security.Cryptography import DESCryptoServiceProvider, CryptoStream, CryptoStreamMode, PaddingMode
from System.IO import MemoryStream, StreamWriter, StreamReader
from hashlib import md5
def s2ab(s):
return Array[Byte](tuple(Byte(ord(c)) for c in s))
def ab2s(ab, len=0):
if len == 0: len = ab.Length
return ''.join([chr(ab[i]) for i in range(len)])
class descrypto():
def __init__(self, password):
pwmd5 = md5(password).digest()
self.key = s2ab(pwmd5[:8])
self.iv = s2ab(pwmd5[8:])
self.des = DESCryptoServiceProvider() # 缺省 des.Mode = CipherMode.CBC
def enc(self, input):
ms = MemoryStream()
encStream = CryptoStream(ms, self.des.CreateEncryptor(self.key, self.iv), CryptoStreamMode.Write)
sw = StreamWriter(encStream)
sw.Write(input)
sw.Flush()
encStream.FlushFinalBlock()
return ab2s(ms.GetBuffer(), ms.Length)
def dec(self, input):
ms = MemoryStream(s2ab(input))
length = len(input)
decStream = CryptoStream(ms, self.des.CreateDecryptor(self.key, self.iv), CryptoStreamMode.Read)
byteArray = Array.CreateInstance(Byte, length)
length = decStream.Read(byteArray, 0, length)
return ab2s(byteArray, length)
本地端 PyCrypto 的封装
# pycrypto.py
from hashlib import md5
from Crypto.Cipher import DES
class descrypto():
def __init__(self, password):
pwmd5 = md5(password).digest()
self.key = pwmd5[:8]
self.iv = pwmd5[8:]
def enc(self, input):
des = DES.new(self.key, DES.MODE_CBC, self.iv)
lastblock = len(input) % 8
if lastblock > 0:
padding = 8 - lastblock
input += padding * chr(padding)
return des.encrypt(input)
def dec(self, input):
des = DES.new(self.key, DES.MODE_CBC, self.iv)
ret = des.decrypt(input)
padding = ord(ret[-1])
for i in range(padding):
if ord(ret[-1 - i]) != padding:
padding = 0
break
if padding > 0:
ret = ret[:-padding]
return ret
建议继续学习:
- 让安卓手机通过代理翻墙的方法 (阅读:7197)
- 网址加密(URL加密)(RC4、PHP、密钥长度可变) (阅读:6966)
- 关于 SOCKS 代理的远端 DNS 解析 (阅读:6460)
- 在浏览器中加密Cookie (阅读:4598)
- 使用bcompiler对PHP文件进行加密 (阅读:4360)
- 使用系统命令实现文件的压缩与加密 (阅读:4045)
- 公钥私钥加密解密数字证书数字签名详解 (阅读:4052)
- HTTP 正向代理与反向代理 (阅读:3925)
- 关于不得不在python中使用代理访问网络的方法 (阅读:3782)
- 可逆的加密方法(Mcrypt Encryption Functions) (阅读:3738)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:qyb 来源: BT的花 blogs
- 标签: 代理 加密
- 发布时间:2010-04-01 08:51:34
- [2527] 代理的加密部分
- [1324] 创业笔记 | 从0到1开公司是什么体验
- [645] vimgtd-在vim(gvim)中实现GT
- [568] 查找第K小的元素
- [68] Oracle MTS模式下 进程地址与会话信
- [64] 【社会化设计】自我(self)部分――欢迎区
- [63] Go Reflect 性能
- [60] android 开发入门
- [60] 图书馆的世界纪录
- [58] 如何拿下简短的域名