技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> 网络系统 --> 代理的加密部分

代理的加密部分

浏览:4515次  出处信息

就是怎么在 PHP/mcrypt 和 PyCrypto 之间 DES(或其他加密算法,比如3DES/RSA/..) 通信的问题,我这里还额外考察了下 .NET 平台的算法

网上询问相关问题的还挺多,尤其是 PHP 和 .NET 之间的 DES 转换。主要是 PHP/mcrypt 隐藏了 padding 的细节,且只保留了 ZERO_PADDING 模式,所以不明白cyrpto原理的不太容易找到症结所在。我的传输方案统一用 pkcs#7 padding.

首先是给服务器端增加的 PKCS#7 PADDING 函数,来自PHP官方函数手册上某人的注释

function padding_pkcs7($crypto, $mode, $dat)
{
        $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 封装

# -*- coding: utf-8 -*-
# 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 的封装

# -*- coding: utf-8 -*-
# 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

建议继续学习:

  1. 让安卓手机通过代理翻墙的方法    (阅读:7157)
  2. 网址加密(URL加密)(RC4、PHP、密钥长度可变)    (阅读:6923)
  3. 关于 SOCKS 代理的远端 DNS 解析    (阅读:6420)
  4. 在浏览器中加密Cookie    (阅读:4566)
  5. 使用bcompiler对PHP文件进行加密    (阅读:4339)
  6. 使用系统命令实现文件的压缩与加密    (阅读:4024)
  7. 公钥私钥加密解密数字证书数字签名详解    (阅读:4013)
  8. HTTP 正向代理与反向代理    (阅读:3901)
  9. 关于不得不在python中使用代理访问网络的方法    (阅读:3750)
  10. 可逆的加密方法(Mcrypt Encryption Functions)    (阅读:3701)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1