IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

代理的加密部分

BT的花 blogs 2010-04-01 08:51:34 累计浏览 8,410 次
本机暂存

就是怎么在 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. 绿盟科技《APT组织研究年鉴》(2026 版)正式发布 (2026-06-16 20:21:10)
  2. 【已复现】Linux内核Fragnesia权限提升漏洞(CVE-2026-46300) (2026-06-15 10:53:58)
  3. 企业文档安全最佳实践(二):给文档上“身份证”——手动标密与智能自动标密 (2026-06-12 17:18:33)

查看更多 安全 文章 →

建议继续学习

  1. 使用gettext来支持PHP的多语言 (累计阅读 39,258)
  2. WordPress插件开发 -- 在插件使用数据库存储数据 (累计阅读 29,157)
  3. Paypal接口详细代码(PHP版,非API接口) (累计阅读 19,404)
  4. 我的PHP,Python和Ruby之路 (累计阅读 13,140)
  5. include(“./file.php”)和include(“file.php”)区别 (累计阅读 12,783)
  6. 15个最好的免费开源电子商务平台 (累计阅读 12,529)
  7. Redis消息队列的若干实现方式 (累计阅读 12,077)
  8. 到底什么是MVC? (累计阅读 11,851)
  9. 整理了一份招PHP高级工程师的面试题 (累计阅读 11,693)
  10. Rolling cURL: PHP并发最佳实践 (累计阅读 11,483)