代码改变世界

C#/Java/PHP DES加密互操作

2013-06-15 19:26  游乐场123  阅读(342)  评论(0编辑  收藏  举报
差异一般产生在加密方式,而且是你没指定的加密方式,或者zeroIV初始向量,填充模式等等,你不指定,各个程序和库处理的方式就会不一样,这就是产生差异的原因。
以PHP的mcrypt_cbc函数为例
 
string mcrypt_cbc ( string $cipher , string $key , string $data , int $mode [, string $iv ] )
 
cbc是工作模式,DES一共有电子密码本模式(ECB)、加密分组链接模式(CBC)、加密反馈模式(CFB)和输出反馈模式(OFB)四种模式,
在使用 CFB 及 OFB 二种模式时,必须要向量初始化 (Initialization vector, IV),CBC 模式也可以使用向量初始化。向量初始化的值在加解密时必须是独一无二的,同时也要保持相同。当加密后的资料输出时,也可同时输出密码钥匙 (例如存在文件中);或者也可以将向量初始化的值与加密后的资料一起输出。http://php.net/manual/en/mcrypt.ciphers.php
 
官方有个手册评论地址可以参考:http://www.php.net/manual/zh/ref.mcrypt.php#69782
java中的加密代码,DES.java类代码:
 

package welcome;

import javax.crypto.*;
import javax.crypto.*;
import java.io.UnsupportedEncodingException;
import java.security.spec.*;
import javax.crypto.spec.*;

public class DES {

    public DES()
    {
    }

     public String encrypt(String str) {

        byte[] enc = null;
        try {
          enc = desEncrypt(str, "abcdefgh");
        }
        catch (Exception ex) {
        }
      
         return new sun.misc.BASE64Encoder().encode(enc);
     }
    
     public static byte[] desEncrypt(String message, String key) throws Exception {
             Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
 
             DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
 
             SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
             SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
             IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));
             cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
 
             return cipher.doFinal(message.getBytes("UTF-8"));
         }
}

 

C#代码
 

using System.Security.Cryptography;
        /// <param name="pToEncrypt">要加密的字符串。</param>
        /// <param name="sKey">密钥,且必须为8位。</param>
        /// <returns>以Base64格式返回的加密字符串。</returns>
        public string Encrypt(string pToEncrypt, string sKey)
        {
            using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
            {
                byte[] inputByteArray = Encoding.UTF8.GetBytes(pToEncrypt);
                des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
                des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(inputByteArray, 0, inputByteArray.Length);
                    cs.FlushFinalBlock();
                    cs.Close();
                }
                string str = Convert.ToBase64String(ms.ToArray());
                ms.Close();
                return str;
            }
        }

        /// <param name="pToDecrypt">要解密的以Base64</param>
        /// <param name="sKey">密钥,且必须为8位。</param>
        /// <returns>已解密的字符串。</returns>
        public string Decrypt(string pToDecrypt, string sKey)
        {
            byte[] inputByteArray = Convert.FromBase64String(pToDecrypt);
            using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
            {
                des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
                des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(inputByteArray, 0, inputByteArray.Length);
                    cs.FlushFinalBlock();
                    cs.Close();
                }
                string str = Encoding.UTF8.GetString(ms.ToArray());
                ms.Close();
                return str;
            }
        }       

 

PHP代码:

 

<?php
class DES {
    var $key;
    var $iv; //偏移量

   
    function DES($key, $iv = 0) {
        //key长度8例如:1234abcd
        $this->key = $key;
        if ($iv == 0) {
            $this->iv = $key; //默认以$key 作为 iv
        } else {
            $this->iv = $iv; //mcrypt_create_iv ( mcrypt_get_block_size (MCRYPT_DES, MCRYPT_MODE_CBC), MCRYPT_DEV_RANDOM );
        }
    }

    function encrypt($str) {
        //加密,返回值使用base64重编码
        $size = mcrypt_get_block_size(MCRYPT_DES, MCRYPT_MODE_CBC);
        $str = $this->pkcs5Pad($str, $size);
        return base64_encode(mcrypt_cbc(MCRYPT_DES, $this->key, $str, MCRYPT_ENCRYPT, $this->iv));
    }

    function decrypt($str) {
        //解密 输入值是base64重编码过的
        $strBin = base64_decode($str);
        $str = mcrypt_cbc(MCRYPT_DES, $this->key, $strBin, MCRYPT_DECRYPT, $this->iv);
        $str = $this->pkcs5Unpad($str);
        return $str;
    }

   
    function pkcs5Unpad($text) {
        $pad = ord($text{strlen($text) - 1});
        if ($pad > strlen($text)) return false;
        if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) return false;
        return substr($text, 0, -1 * $pad);
    }

   
    function pkcs5Pad($text, $blocksize) {
        $pad = $blocksize - (strlen($text) % $blocksize);
        return $text . str_repeat(chr($pad), $pad);
    }

}
?>