zoukankan      html  css  js  c++  java
  • C#/Java/PHP DES加密互操作

    差异一般产生在加密方式,而且是你没指定的加密方式,或者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);
        }

    }
    ?>

  • 相关阅读:
    最全前端面试题
    经常犯的思维误区
    鸿蒙系统发布会
    前端面试题
    怎么做一个竖排文字?
    canvas-台球玩法
    canvas-自由落体球
    canvas-画一颗心
    canvas-学写字
    常用的65条正则表达式
  • 原文地址:https://www.cnblogs.com/youlechang123/p/3137917.html
Copyright © 2011-2022 走看看