C++,C#,android,nodejs,php通用DES加密解密算法

DES通用加密解密算法之android

package com.gemgin.common;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

public class DESUtil {
    //解密方式如下:
    //new String(DESUtil.decrypt(Base64.decode("pKkeY+XC8zss888ikXFsSpfPcztgDNE", 0)))
    /**
     * 加密函数
     * @param data 加密数据
     * @param key  密钥
     * @return 返回加密后的数据
     */
       public static byte[] encrypt(byte[] data,byte[] key) {
        try {
            // DES算法要求有一个可信任的随机数源
            SecureRandom sr = new SecureRandom();
            // 从原始密钥数据创建DESKeySpec对象
            DESKeySpec dks = new DESKeySpec(key);
            // 创建一个密匙工厂,然后用它把DESKeySpec转换成
            // 一个SecretKey对象
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey secretKey = keyFactory.generateSecret(dks);
            // using DES in ECB mode
            Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
            // 用密匙初始化Cipher对象
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, sr);
            // 执行加密操作
            byte encryptedData[] = cipher.doFinal(data);
            return encryptedData;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
     }

     public static String enCrypto2(String str, byte[] sn) {
        int[] snNum=new int[str.length()];
        String result="";
        String temp="";

        for(int i=0,j=0;i<str.length();i++,j++){
            if(j==sn.length)
                j=0;

            snNum[i]=(int)str.charAt(i)^(int)sn[j];
        }

        for(int k=0;k<str.length();k++){
            temp=""+(char)snNum[k];
            result+=temp;
        }
        return result;

    }
    private static String toHexUtil(int n){
        String rt="";
        switch(n){
        case 10:rt+="A";break;
        case 11:rt+="B";break;
        case 12:rt+="C";break;
        case 13:rt+="D";break;
        case 14:rt+="E";break;
        case 15:rt+="F";break;
        default:
            rt+=n;
        }
        return rt;
    }

   public static String toHex(int n){
            StringBuilder sb=new StringBuilder();
            if(n/16==0){
                return toHexUtil(n);
            }else{
                String t=toHex(n/16);
                int nn=n%16;
                sb.append(t).append(toHexUtil(nn));
            }
            return sb.toString();
        }


    public static String parseAscii(String str){
        StringBuilder sb=new StringBuilder();
        byte[] bs=str.getBytes();
        for(int i=0;i<bs.length;i++)
            sb.append(toHex(bs[i]));
        return sb.toString();
    }

    /**
     * 加密(使用DES算法)
     * 
     * @param txt
     *            需要加密的文本
     * @param key
     *            密钥
     * @return 成功加密的文本
     * @throws InvalidKeySpecException
     * @throws InvalidKeyException
     * @throws NoSuchPaddingException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     */
   public static String enCrypto(String txt, String key)
            throws InvalidKeySpecException, InvalidKeyException,
            NoSuchPaddingException, IllegalBlockSizeException,
            BadPaddingException {
        StringBuffer sb = new StringBuffer();
        DESKeySpec desKeySpec = new DESKeySpec(key.getBytes());
        SecretKeyFactory skeyFactory = null;
        Cipher cipher = null;
        try {
            skeyFactory = SecretKeyFactory.getInstance("DES");
            //cipher = Cipher.getInstance("DES");
            cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        SecretKey deskey = skeyFactory.generateSecret(desKeySpec);
        cipher.init(Cipher.ENCRYPT_MODE, deskey);
        byte[] cipherText = cipher.doFinal(txt.getBytes());
        for (int n = 0; n < cipherText.length; n++) {
            String stmp = (java.lang.Integer.toHexString(cipherText[n] & 0XFF));

            if (stmp.length() == 1) {
                sb.append("0" + stmp);
            } else {
                sb.append(stmp);
            }
        }
        return sb.toString().toUpperCase();
    }
    /**
     * 解密函数
     * @param data 解密数据
     * @param key 密钥
     * @return 返回解密后的数据
     */
    public static String decrypt(byte[] data,byte[] key) {
        try {
            // DES算法要求有一个可信任的随机数源
            SecureRandom sr = new SecureRandom();
            // byte rawKeyData[] = /* 用某种方法获取原始密匙数据 */;
            // 从原始密匙数据创建一个DESKeySpec对象
            DESKeySpec dks = new DESKeySpec(key);
            // 创建一个密匙工厂,然后用它把DESKeySpec对象转换成
            // 一个SecretKey对象
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey secretKey = keyFactory.generateSecret(dks);
            // using DES in ECB mode
            Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
            // 用密匙初始化Cipher对象
            cipher.init(Cipher.DECRYPT_MODE, secretKey, sr);
            // 正式执行解密操作
            byte decryptedData[] = cipher.doFinal(data);

            return new String(decryptedData);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}


byte[] n_byte=  new byte[]{1,2,1,8,0,1,5,1};
username=username.toUpperCase();
String tKey="123456";
byte[] m_byte = tKey.getBytes();
for (int i=0;i<tKey.length();i++)
{
  n_byte[i]=(byte) (m_byte[i]-48);//m_byte[i] 保存是ASCII码
}      
mPassword= DESUtil.enCrypto2(username,n_byte); //加密

DES通用加密解密算法之nodjs

'use strict';
//加密组件
let crypto = require('crypto');
/**
 * md5 hash
 *
 * @param str
 * @returns md5 str
 */
exports.md5 = function md5(str) {
  let md5sum = crypto.createHash('md5');
  md5sum.update(str);
  str = md5sum.digest('hex');
  return str;
};


/**
 * 加密函数
 * @param str 源串
 * @param secret  因子
 * @returns str
 */
exports.encrypt = function encrypt(str, secret) {
  let cipher = crypto.createCipher('aes192', secret);
  let enc = cipher.update(str, 'utf8', 'hex');
  enc += cipher.final('hex');
  return enc;
};

/**
 * 解密
 * @param str
 * @param secret
 * @returns str
 */
exports.decrypt = function decrypt(str, secret) {
  let decipher = crypto.createDecipher('aes192', secret);
  let dec = decipher.update(str, 'hex', 'utf8');
  dec += decipher.final('utf8');
  return dec;
};

exports.random = function (len) {
  return crypto.randomBytes(len || 16).toString('hex');
}

exports.hashPassword = function (password, secret) {
  if (!password) return '';
  let encrypred;
  try {
    encrypred = crypto.createHmac('sha1', secret).update(password).digest('hex');
    return encrypred;
  } catch (err) {
    return '';
  }
};

/**
 * guid
 * @returns str
 */
exports.guid = function () {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
    var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
    return v.toString(16);
  });
};


/**
 * 加密函数
 * @param str 源串
 * @param secret  因子
 * @returns str
 */
exports.encryptDES= function encrypt(plaintext, xkey) {

  var desKey =this.md5(xkey).substr(0,8).toUpperCase();
  var key = Buffer.from(desKey);
  var iv = Buffer.from(desKey);
  var cipher = crypto.createCipheriv('des-cbc', key, iv);

  cipher.setAutoPadding(true); //default true
  var ciph = cipher.update(plaintext, 'utf8', 'hex');
  ciph += cipher.final('hex');
  return ciph.toUpperCase();
};

/**
 * 解密
 * @param str
 * @param secret
 * @returns str
 */
exports.decryptDES = function decrypt(encrypt_text, xkey) {
  var desKey =this.md5(xkey).substr(0,8).toUpperCase();
  var key = Buffer.from(desKey);
  var iv = Buffer.from(desKey);
  var decipher = crypto.createDecipheriv('des-cbc', key, iv);
  decipher.setAutoPadding(true);
  var txt = decipher.update(encrypt_text, 'hex', 'utf8');
  txt += decipher.final('utf8');
  return txt;
};
//加密
let eGuidKey = crypto.encryptDES(obj.GuidKey,obj.DesKey)
//解密
let eGuidKey = crypto.decryptDES(obj.GuidKey,obj.DesKey)

DES通用加密解密算法之php

<?php
namespace toolkit;
class DescryptInfo 
{
      var $key;
    var $iv; //偏移量

    function __construct($pkey) {    
        //php的构造函数了 
        $this->key = $pkey;
        $this->iv = $pkey;
    }

    function encrypt($str) {
    //加密,返回大写十六进制字符串
        $size = mcrypt_get_block_size ( MCRYPT_DES, MCRYPT_MODE_CBC );
        $str = $this->pkcs5Pad ( $str, $size );
        return strtoupper( bin2hex( mcrypt_cbc(MCRYPT_DES, $this->key, $str, MCRYPT_ENCRYPT, $this->iv ) ) );
    }

    function decrypt($str) {
    //解密
        $strBin = $this->hex2bin( strtolower( $str ) );
        $str = mcrypt_cbc( MCRYPT_DES, $this->key, $strBin, MCRYPT_DECRYPT, $this->iv );
        $str = $this->pkcs5Unpad( $str );
        return $str;
    }

    function hex2bin($hexData) {
        $binData = "";
        for($i = 0; $i < strlen ( $hexData ); $i += 2) {
            $binData .= chr ( hexdec ( substr ( $hexData, $i, 2 ) ) );
        }
        return $binData;
    }

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

    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 );
    }
}
?>

$desKey=strtoupper(substr(MD5($desKey),0,8));
$Des = new DescryptInfo($desKey);   
$key = $Des->decrypt($idNo); //解密key
$key = $Des->encrypt($idNo); //加密key

DES通用加密解密算法之C++

/* 
*   CDesEnter 函数说明: 
*     des加密/解密入口 
*   返回: 
*     1则成功,0失败 
*   参数: 
*     in 需要加密或解密的数据  
*         注意:in缓冲区的大小必须和datalen相同. 
*     out 加密后或解密后输出。 
*         注意:out缓冲区大小必须是8的倍数而且比datalen大或者相等。 
*         如datalen=7,out缓冲区的大小应该是8,datalen=8,out缓冲区的大小应该是8, 
*         datalen=9,out缓冲区的大小应该是16,依此类推。 
*     datalen 数据长度(字节)。  
*         注意:datalen 必须是8的倍数。 
*     key 8个字节的加密或解密的密码。 
*     type 是对数据进行加密还是解密 
*         0 表示加密 1 表示解密 
*/ 
BOOL CDesEnter(LPCBYTE in, LPBYTE out, int datalen, const BYTE key[8], BOOL type) 
{ 
    //判断输入参数是否正确,失败的情况为: 
    //!in: in指针(输入缓冲)无效 
    //!out: out指针(输出缓冲)无效 
    //datalen<1: 数据长度不正确 
    //!key: 加/解密密码无效 
    //type && ((datalen % 8) !=0:选择解密方式但是输入密文不为8的倍数 
    if((!in) || (!out) || (datalen<1) || (!key) || (type && ((datalen % 8) !=0))) 
        return false; 


    if(type==0) //选择的模式是加密 
    { 
        // 用于存储待加密字串最后的若干字节 
        // DES算法是以8个字节为单位进行加密,如果待加密字串以8为单位分段加密时,最后一段不足 
        //8字节,则在后面补0,使其最后一段的长度为8字节 
        // te8bit是作为存储待加密字串最后一段(不足8字节)的变量 
        BYTE te8bit[8]={0,0,0,0,0,0,0,0}; 

        // 这是待加密字串的调整长度 
        // 如果原始长度是8的整数倍,则调整长度的值和原来的长度一样 
        // 如果原始长度不是8的整数倍,则调整长度的值是能被8整除且不大于原来长度的最大整数。 
        //也就是不需要补齐的块的总长度。 
        int te_fixlen = datalen - (datalen % 8); 

        // 将待加密密文以8为单位分段,把最后长度不足8的一段存储到te8bit中。 
        for(int i = 0; i < (datalen % 8); i++) 
            te8bit[i] = in[te_fixlen + i]; 

        // 将待加密字串分以8字节为单位分段加密 
        for(i = 0; i < te_fixlen; i += 8) 
            XOR(in + i, key, out + i); 

        // 如果待加密字串不是8的整数倍,则将最后一段补齐(补0)后加密 
        if(datalen % 8 != 0) 
            XOR(te8bit, key, out + datalen / 8 * 8); 
    } 
    else   //选择的模式是解密 
    { 
        // 将密文以8字节为单位分段解密 
        for(int i = 0; i < datalen; i += 8) 
            XOR(in + i, key, out + i); 
    } 
    return true; 
} 


void XOR(const BYTE in1[8], const BYTE in2[8], BYTE out[8]) 
{ 
    for(int i = 0; i < 8; i++) 
        out[i] = in1[i] ^ in2[i];  
} 

CString Convert2Hex(LPCTSTR p)
{
    TCHAR sz[4]={0};
    CString str(_T(""));
    for(int i=0;i<(int)_tcslen(p);i++)
    {
        _stprintf(sz,_T("%02X"),p[i]&0xFF);
        str += sz;
    }
    return str;
}

////////////////////////////////////////////////////////////////////////
CString tUser=m_UserName; //机器码
tUser.MakeUpper();  //转换成大写

CString tKey =m_Key;      //密钥
int datalen=tUser.GetLength();
LPBYTE reg = new BYTE [datalen];

m_byte=(BYTE *)tKey.GetBuffer(tKey.GetLength());  //cstring转BYTE

for (int i=0;i<tKey.GetLength();i++)
{
 n_byte[i]=m_byte[i]-48;//m_byte[i] 保存是ASCII码
}

CDesEnter((LPCBYTE)(LPCSTR)tUser,reg,datalen,n_byte,0);
CString tPass=((CString)reg).Mid(0,datalen);
tPass=Convert2Hex(tPass);  // 转ASCII码

DES通用加密解密算法之C#

///<summary>
/// DES加密/解密类。
///</summary>
public abstract class DESEncrypt
{

    public DESEncrypt()
    {

    }

    #region========加密========

    ///<summary>
    /// 加密
    ///</summary>
    ///<param name="Text"></param>
    ///<returns></returns>
    public static string Encrypt(string Text)
    {
      return Encrypt(Text, "123456");
    }

   ///<summary> 
   /// 加密数据 
   ///</summary> 
   ///<param name="Text"></param> 
   ///<param name="sKey"></param> 
   ///<returns></returns> 
   public static string Encrypt(string Text, string sKey)
   {
      Text = Text.Trim();
      sKey = sKey.Trim();
      DESCryptoServiceProvider des = new DESCryptoServiceProvider();
      byte[] inputByteArray;
      inputByteArray = Encoding.Default.GetBytes(Text);
      des.Key = ASCIIEncoding.ASCII.GetBytes(MD5(sKey).Substring(0, 8));
      des.IV = ASCIIEncoding.ASCII.GetBytes(MD5(sKey).Substring(0, 8));
      System.IO.MemoryStream ms = new System.IO.MemoryStream();
      CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
      cs.Write(inputByteArray, 0, inputByteArray.Length);
      cs.FlushFinalBlock();
      StringBuilder ret = new StringBuilder();
      foreach (byte b in ms.ToArray())
      {
       ret.AppendFormat("   {0:X2}", b);
      }
      return ret.ToString();
   }

   #endregion

   #region ========解密========

   ///<summary>
   /// 解密
   ///</summary>
   ///<param name="Text"></param>
   ///<returns></returns>
   public static string Decrypt(string Text)
   {
      return Decrypt(Text, "123456");
}

   ///<summary> 
   /// 解密数据 
   ///</summary> 
   ///<param name="Text"></param> 
   ///<param name="sKey"></param> 
   ///<returns></returns> 
   public static string Decrypt(string Text, string sKey)
   {
      Text = Text.Trim();
      sKey = sKey.Trim();
      DESCryptoServiceProvider des = new DESCryptoServiceProvider();
      int len;
      len = Text.Length / 2;
      byte[] inputByteArray = new byte[len];
      int x, i;
      for (x = 0; x < len; x++)
      {
        i = Convert.ToInt32(Text.Substring(x * 2, 2), 16);
        inputByteArray[x] = (byte)i;
      }
      des.Key = ASCIIEncoding.ASCII.GetBytes(MD5(sKey).Substring(0, 8));
      des.IV = ASCIIEncoding.ASCII.GetBytes(MD5(sKey).Substring(0, 8));
      System.IO.MemoryStream ms = new System.IO.MemoryStream();
      CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
      cs.Write(inputByteArray, 0, inputByteArray.Length);
      cs.FlushFinalBlock();
      return Encoding.Default.GetString(ms.ToArray());
    }

   public static string MD5(string str)
   {
      //微软md5方法参考return FormsAuthentication.HashPasswordForStoringInConfigFile(str, "md5");
      byte[] b = Encoding.Default.GetBytes(str);
      b = new MD5CryptoServiceProvider().ComputeHash(b);
      string ret = "";
      for (int i = 0; i < b.Length; i++)
      ret += b[i].ToString("X").PadLeft(2, '0');
      return ret;
    }

    #endregion
}

标签:MD5CryptoServiceProvider ComputeHash DESCryptoServiceProvider pkcs5Pad des-cbc PKCS5Padding