您现在的位置是:网站首页> C#技术

Golang、PHP、Java、C#、ObjectC互通DES加密与解密

摘要

在完成一个大项目时候,我们要用到多语言来开发接口,每个模块可能分配到各小组中,各小组成员用到语言往往不一样,在向接口传递参数的时候,就要用到加密与解密。


在网上找了一些,这篇文章中有通用的写法,《PHP、JAVA、C#、Object-C 通用的DES加密》。


我只对PHP和Golang加密与解密进行了修改,其它语言并没有修改!


PHP:


/**

 * @desc DES加密码与解密

*/

class Des {

//密钥8位

public $key = '256&#@$M';

 

/**

* @desc 加密返回大写十六进制字符串

* @param string $str

* @return string

*/

public function encrypt($str) {

$size = mcrypt_get_block_size (MCRYPT_DES, MCRYPT_MODE_CBC);

$str = $this->pkcs5Pad($str, $size);

return strtoupper(bin2hex( mcrypt_encrypt(MCRYPT_DES, $this->key, $str, MCRYPT_MODE_CBC, $this->key)));

}

 

/**

* @desc 解密

* @param string $str

* @return string

*/

public function decrypt($str) {

$strBin = $this->hex2bin(strtolower($str));

$str = mcrypt_decrypt(MCRYPT_DES, $this->key, $strBin, MCRYPT_MODE_CBC, $this->key);

$str = $this->pkcs5Unpad($str);

return $str;

}

 

public function hex2bin($hexData) {

$binData = '';

for($i = 0; $i < strlen ($hexData ); $i += 2) {

$binData .= chr(hexdec(substr($hexData, $i, 2)));

}

return $binData;

}

 

public function pkcs5Pad($text, $blocksize) {

$pad = $blocksize - (strlen($text) % $blocksize);

return $text . str_repeat(chr($pad), $pad);

}

 

public 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);

}

 

}

 

$obj = new DES();

echo '<pre>';

echo $str = $obj->encrypt('123456');

echo '<br/>========================================<br/>';

echo $obj->decrypt($str);


下面再介绍一下Golang的,这里有篇文章详细的介绍了《Go加密解密之AES》,并附有代码。


Golang:


package main

 

import (

"bytes"

"crypto/cipher"

"crypto/des"

"encoding/base64"

"fmt"

)

 

func main() {

// DES 加解密

testDes()

// 3DES加解密

test3Des()

}

 

func testDes() {

key := []byte("256&#@$M")

result, err := DesEncrypt([]byte("123456"), key)

if err != nil {

panic(err)

}

fmt.Println(base64.StdEncoding.EncodeToString(result))

hexstr := fmt.Sprintf("%X", result)

fmt.Println(hexstr)

origData, err := DesDecrypt(result, key)

if err != nil {

panic(err)

}

fmt.Println("=======")

fmt.Println(string(origData))

}

 

func test3Des() {

key := []byte("256&#@$Msefiel#fi32lf3e!")

result, err := TripleDesEncrypt([]byte("123456"), key)

if err != nil {

panic(err)

}

fmt.Println(base64.StdEncoding.EncodeToString(result))

origData, err := TripleDesDecrypt(result, key)

if err != nil {

panic(err)

}

fmt.Println(string(origData))

}

 

func DesEncrypt(origData, key []byte) ([]byte, error) {

block, err := des.NewCipher(key)

if err != nil {

return nil, err

}

origData = PKCS5Padding(origData, block.BlockSize())

// origData = ZeroPadding(origData, block.BlockSize())

blockMode := cipher.NewCBCEncrypter(block, key)

crypted := make([]byte, len(origData))

// 根据CryptBlocks方法的说明,如下方式初始化crypted也可以

// crypted := origData

blockMode.CryptBlocks(crypted, origData)

return crypted, nil

}

 

func DesDecrypt(crypted, key []byte) ([]byte, error) {

block, err := des.NewCipher(key)

if err != nil {

return nil, err

}

blockMode := cipher.NewCBCDecrypter(block, key)

origData := make([]byte, len(crypted))

// origData := crypted

blockMode.CryptBlocks(origData, crypted)

origData = PKCS5UnPadding(origData)

// origData = ZeroUnPadding(origData)

return origData, nil

}

 

// 3DES加密

func TripleDesEncrypt(origData, key []byte) ([]byte, error) {

block, err := des.NewTripleDESCipher(key)

if err != nil {

return nil, err

}

origData = PKCS5Padding(origData, block.BlockSize())

// origData = ZeroPadding(origData, block.BlockSize())

blockMode := cipher.NewCBCEncrypter(block, key[:8])

crypted := make([]byte, len(origData))

blockMode.CryptBlocks(crypted, origData)

return crypted, nil

}

 

// 3DES解密

func TripleDesDecrypt(crypted, key []byte) ([]byte, error) {

block, err := des.NewTripleDESCipher(key)

if err != nil {

return nil, err

}

blockMode := cipher.NewCBCDecrypter(block, key[:8])

origData := make([]byte, len(crypted))

// origData := crypted

blockMode.CryptBlocks(origData, crypted)

origData = PKCS5UnPadding(origData)

// origData = ZeroUnPadding(origData)

return origData, nil

}

 

func ZeroPadding(ciphertext []byte, blockSize int) []byte {

padding := blockSize - len(ciphertext)%blockSize

padtext := bytes.Repeat([]byte{0}, padding)

return append(ciphertext, padtext...)

}

 

func ZeroUnPadding(origData []byte) []byte {

return bytes.TrimRightFunc(origData, func(r rune) bool {

return r == rune(0)

})

}

 

func PKCS5Padding(ciphertext []byte, blockSize int) []byte {

padding := blockSize - len(ciphertext)%blockSize

padtext := bytes.Repeat([]byte{byte(padding)}, padding)

return append(ciphertext, padtext...)

}

 

func PKCS5UnPadding(origData []byte) []byte {

length := len(origData)

// 去掉最后一个字节 unpadding 次

unpadding := int(origData[length-1])

return origData[:(length - unpadding)]

}

其它几个版本的可以看一下《PHP、JAVA、C#、Object-C 通用的DES加密》


这里也顺便Copy一下过来~

C#:


public class MyDes

    {

        /// <summary>

        /// DES加密方法

        /// </summary>

        /// <param name="strPlain">明文</param>

        /// <param name="strDESKey">密钥</param>

        /// <param name="strDESIV">向量</param>

        /// <returns>密文</returns>

        public static string Encode(string source, string _DESKey)

        {

            StringBuilder sb = new StringBuilder();

            using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())

            {

                byte[] key = ASCIIEncoding.ASCII.GetBytes(_DESKey);

                byte[] iv = ASCIIEncoding.ASCII.GetBytes(_DESKey);

                byte[] dataByteArray = Encoding.UTF8.GetBytes(source);

                des.Mode = System.Security.Cryptography.CipherMode.CBC;

                des.Key = key;

                des.IV = iv;

                string encrypt = "";

                using (MemoryStream ms = new MemoryStream())

                using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write))

                {

                    cs.Write(dataByteArray, 0, dataByteArray.Length);

                    cs.FlushFinalBlock();

                    encrypt = Convert.ToBase64String(ms.ToArray());

                }

                return encrypt;

            }

        }

 

        /// <summary>

        /// 进行DES解密。

        /// </summary>

        /// <param name="pToDecrypt">要解密的base64串</param>

        /// <param name="sKey">密钥,且必须为8位。</param>

        /// <returns>已解密的字符串。</returns>

        public static string Decode(string source, string sKey)

        {

            byte[] inputByteArray = System.Convert.FromBase64String(source);//Encoding.UTF8.GetBytes(source);

            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;

            }

        }

    }

Object C:


/***  JoDes.h ***/

 

#import <Foundation/Foundation.h>

#import <CommonCrypto/CommonDigest.h>

#import <CommonCrypto/CommonCryptor.h>

 

@interface JoDes : NSObject

 

+ (NSString *) encode:(NSString *)str key:(NSString *)key;

+ (NSString *) decode:(NSString *)str key:(NSString *)key;

 

@end

 

 

/***  JoDes.m ***/

//

//  XLEncrytHelper.m

//  NewHoldGold

//

//  Created by 梁鑫磊 on 13-12-27.

//  Copyright (c) 2013年 zsgjs. All rights reserved.

//

 

#import "JoDes.h"

 

@interface JoDes()

 

+ (NSString *) encodeBase64WithString:(NSString *)strData;

+ (NSString *) encodeBase64WithData:(NSData *)objData;

+ (NSData *) decodeBase64WithString:(NSString *)strBase64;

 

+ (NSString *)doCipher:(NSString *)sTextIn key:(NSString *)sKey

                  context:(CCOperation)encryptOrDecrypt;

 

@end

 

@implementation JoDes

 

+ (NSString *) encode:(NSString *)str key:(NSString *)key

{

    // doCipher 不能编汉字,所以要进行 url encode

    NSMutableString* str1 = [JoDes urlEncode:str];

    NSMutableString* encode = [NSMutableString stringWithString:[JoDes doCipher:str1 key:key context:kCCEncrypt]];

    [JoDes formatSpecialCharacters:encode];

    return encode;

}

 

+ (NSString *) decode:(NSString *)str key:(NSString *)key

{

    NSMutableString *str1 = [NSMutableString stringWithString:str];

    [JoDes reformatSpecialCharacters:str1];

    NSString *rt = [JoDes doCipher:str1 key:key context:kCCDecrypt];

    return rt;

}

 

+ (NSMutableString *)urlEncode:(NSString*)str

{

    NSMutableString* encodeStr = [NSMutableString stringWithString:[str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

    [encodeStr replaceOccurrencesOfString:@"+" withString:@"%2B" options:NSWidthInsensitiveSearch range:NSMakeRange(0, [encodeStr length])];

    [encodeStr replaceOccurrencesOfString:@"/" withString:@"%2F" options:NSWidthInsensitiveSearch range:NSMakeRange(0, [encodeStr length])];

    return encodeStr;

}

 

+ (void)formatSpecialCharacters:(NSMutableString *)str

{

    [str replaceOccurrencesOfString:@"+" withString:@"$$" options:NSWidthInsensitiveSearch range:NSMakeRange(0, [str length])];

    [str replaceOccurrencesOfString:@"/" withString:@"@@" options:NSWidthInsensitiveSearch range:NSMakeRange(0, [str length])];

}

 

 

+ (void)reformatSpecialCharacters:(NSMutableString *)str

{

    [str replaceOccurrencesOfString:@"$$" withString:@"+" options:NSWidthInsensitiveSearch range:NSMakeRange(0, [str length])];

    [str replaceOccurrencesOfString:@"@@" withString:@"/" options:NSWidthInsensitiveSearch range:NSMakeRange(0, [str length])];

}

 

+ (NSString *)encodeBase64WithString:(NSString *)strData {

    return [JoDes encodeBase64WithData:[strData dataUsingEncoding:NSUTF8StringEncoding]];

}

 

 

+ (NSString *)encodeBase64WithData:(NSData *)objData {

    NSString *encoding = nil;

    unsigned char *encodingBytes = NULL;

    @try {

        static char encodingTable[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

        static NSUInteger paddingTable[] = {0,2,1};

         

        NSUInteger dataLength = [objData length];

        NSUInteger encodedBlocks = (dataLength * 8) / 24;

        NSUInteger padding = paddingTable[dataLength % 3];

        if( padding > 0 ) encodedBlocks++;

        NSUInteger encodedLength = encodedBlocks * 4;

         

        encodingBytes = malloc(encodedLength);

        if( encodingBytes != NULL ) {

            NSUInteger rawBytesToProcess = dataLength;

            NSUInteger rawBaseIndex = 0;

            NSUInteger encodingBaseIndex = 0;

            unsigned char *rawBytes = (unsigned char *)[objData bytes];

            unsigned char rawByte1, rawByte2, rawByte3;

            while( rawBytesToProcess >= 3 ) {

                rawByte1 = rawBytes[rawBaseIndex];

                rawByte2 = rawBytes[rawBaseIndex+1];

                rawByte3 = rawBytes[rawBaseIndex+2];

                encodingBytes[encodingBaseIndex] = encodingTable[((rawByte1 >> 2) & 0x3F)];

                encodingBytes[encodingBaseIndex+1] = encodingTable[((rawByte1 << 4) & 0x30) | ((rawByte2 >> 4) & 0x0F) ];

                encodingBytes[encodingBaseIndex+2] = encodingTable[((rawByte2 << 2) & 0x3C) | ((rawByte3 >> 6) & 0x03) ];

                encodingBytes[encodingBaseIndex+3] = encodingTable[(rawByte3 & 0x3F)];

                 

                rawBaseIndex += 3;

                encodingBaseIndex += 4;

                rawBytesToProcess -= 3;

            }

            rawByte2 = 0;

            switch (dataLength-rawBaseIndex) {

                case 2:

                    rawByte2 = rawBytes[rawBaseIndex+1];

                case 1:

                    rawByte1 = rawBytes[rawBaseIndex];

                    encodingBytes[encodingBaseIndex] = encodingTable[((rawByte1 >> 2) & 0x3F)];

                    encodingBytes[encodingBaseIndex+1] = encodingTable[((rawByte1 << 4) & 0x30) | ((rawByte2 >> 4) & 0x0F) ];

                    encodingBytes[encodingBaseIndex+2] = encodingTable[((rawByte2 << 2) & 0x3C) ];

                    // we can skip rawByte3 since we have a partial block it would always be 0

                    break;

            }

            // compute location from where to begin inserting padding, it may overwrite some bytes from the partial block encoding

            // if their value was 0 (cases 1-2).

            encodingBaseIndex = encodedLength - padding;

            while( padding-- > 0 ) {

                encodingBytes[encodingBaseIndex++] = '=';

            }

            encoding = [[NSString alloc] initWithBytes:encodingBytes length:encodedLength encoding:NSASCIIStringEncoding];

        }

    }

    @catch (NSException *exception) {

        encoding = nil;

        NSLog(@"WARNING: error occured while tring to encode base 32 data: %@", exception);

    }

    @finally {

        if( encodingBytes != NULL ) {

            free( encodingBytes );

        }

    }

    return encoding;

     

}

 

+ (NSData *)decodeBase64WithString:(NSString *)strBase64 {

    NSData *data = nil;

    unsigned char *decodedBytes = NULL;

    @try {

#define __ 255

        static char decodingTable[256] = {

            __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__,  // 0x00 - 0x0F

            __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__,  // 0x10 - 0x1F

            __,__,__,__, __,__,__,__, __,__,__,62, __,__,__,63,  // 0x20 - 0x2F

            52,53,54,55, 56,57,58,59, 60,61,__,__, __, 0,__,__,  // 0x30 - 0x3F

            __, 0, 1, 2,  3, 4, 5, 6,  7, 8, 9,10, 11,12,13,14,  // 0x40 - 0x4F

            15,16,17,18, 19,20,21,22, 23,24,25,__, __,__,__,__,  // 0x50 - 0x5F

            __,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,  // 0x60 - 0x6F

            41,42,43,44, 45,46,47,48, 49,50,51,__, __,__,__,__,  // 0x70 - 0x7F

            __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__,  // 0x80 - 0x8F

            __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__,  // 0x90 - 0x9F

            __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__,  // 0xA0 - 0xAF

            __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__,  // 0xB0 - 0xBF

            __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__,  // 0xC0 - 0xCF

            __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__,  // 0xD0 - 0xDF

            __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__,  // 0xE0 - 0xEF

            __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__,  // 0xF0 - 0xFF

        };

        strBase64 = [strBase64 stringByReplacingOccurrencesOfString:@"=" withString:@""];

        NSData *encodedData = [strBase64 dataUsingEncoding:NSASCIIStringEncoding];

        unsigned char *encodedBytes = (unsigned char *)[encodedData bytes];

         

        NSUInteger encodedLength = [encodedData length];

        NSUInteger encodedBlocks = (encodedLength+3) >> 2;

        NSUInteger expectedDataLength = encodedBlocks * 3;

         

        unsigned char decodingBlock[4];

         

        decodedBytes = malloc(expectedDataLength);

        if( decodedBytes != NULL ) {

             

            NSUInteger i = 0;

            NSUInteger j = 0;

            NSUInteger k = 0;

            unsigned char c;

            while( i < encodedLength ) {

                c = decodingTable[encodedBytes[i]];

                i++;

                if( c != __ ) {

                    decodingBlock[j] = c;

                    j++;

                    if( j == 4 ) {

                        decodedBytes[k] = (decodingBlock[0] << 2) | (decodingBlock[1] >> 4);

                        decodedBytes[k+1] = (decodingBlock[1] << 4) | (decodingBlock[2] >> 2);

                        decodedBytes[k+2] = (decodingBlock[2] << 6) | (decodingBlock[3]);

                        j = 0;

                        k += 3;

                    }

                }

            }

             

            // Process left over bytes, if any

            if( j == 3 ) {

                decodedBytes[k] = (decodingBlock[0] << 2) | (decodingBlock[1] >> 4);

                decodedBytes[k+1] = (decodingBlock[1] << 4) | (decodingBlock[2] >> 2);

                k += 2;

            } else if( j == 2 ) {

                decodedBytes[k] = (decodingBlock[0] << 2) | (decodingBlock[1] >> 4);

                k += 1;

            }

            data = [[NSData alloc] initWithBytes:decodedBytes length:k];

        }

    }

    @catch (NSException *exception) {

        data = nil;

        NSLog(@"WARNING: error occured while decoding base 32 string: %@", exception);

    }

    @finally {

        if( decodedBytes != NULL ) {

            free( decodedBytes );

        }

    }

    return data;

     

}

 

 

+ (NSString *)doCipher:(NSString *)sTextIn key:(NSString *)sKey

                  context:(CCOperation)encryptOrDecrypt {

    NSStringEncoding EnC = NSUTF8StringEncoding;

     

    NSMutableData *dTextIn;

    if (encryptOrDecrypt == kCCDecrypt) {

        dTextIn = [[JoDes decodeBase64WithString:sTextIn] mutableCopy];

    }

    else{

        dTextIn = [[sTextIn dataUsingEncoding: EnC] mutableCopy];

    }

    NSMutableData * dKey = [[sKey dataUsingEncoding:EnC] mutableCopy];

    [dKey setLength:kCCBlockSizeDES];

    uint8_t *bufferPtr1 = NULL;

    size_t bufferPtrSize1 = 0;

    size_t movedBytes1 = 0;

    //uint8_t iv[kCCBlockSizeDES];

    //memset((void *) iv, 0x0, (size_t) sizeof(iv));

    //    Byte iv[] = {0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF};

    bufferPtrSize1 = ([sTextIn length] + kCCKeySizeDES) & ~(kCCKeySizeDES -1);

    bufferPtr1 = malloc(bufferPtrSize1 * sizeof(uint8_t));

    memset((void *)bufferPtr1, 0x00, bufferPtrSize1);

     

    CCCrypt(encryptOrDecrypt, // CCOperation op

            kCCAlgorithmDES, // CCAlgorithm alg

            kCCOptionPKCS7Padding, // CCOptions options

            [dKey bytes], // const void *key

            [dKey length], // size_t keyLength //

            [dKey bytes], // const void *iv

            [dTextIn bytes], // const void *dataIn

            [dTextIn length],  // size_t dataInLength

            (void *)bufferPtr1, // void *dataOut

            bufferPtrSize1,     // size_t dataOutAvailable

            &movedBytes1);

     

    //[dTextIn release];

    //[dKey release];

     

    NSString * sResult;

    if (encryptOrDecrypt == kCCDecrypt){

        sResult = [[NSString alloc] initWithData:[NSData dataWithBytes:bufferPtr1 length:movedBytes1] encoding:EnC];

        free(bufferPtr1);

    }

    else {

        NSData *dResult = [NSData dataWithBytes:bufferPtr1 length:movedBytes1];

        free(bufferPtr1);

        sResult = [JoDes encodeBase64WithData:dResult];

    }

    return sResult;

}

Java:


package com.example.aric.test;

 

import javax.crypto.Cipher;

import javax.crypto.SecretKey;

import javax.crypto.SecretKeyFactory;

import javax.crypto.spec.DESKeySpec;

import javax.crypto.spec.IvParameterSpec;

 

import android.util.Base64;

 

public class DES {

 

    public final static String DES_KEY_STRING = "ABSujsuu";

     

    public static String encrypt(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 encodeBase64(cipher.doFinal(message.getBytes("UTF-8")));

    }

 

    public static String decrypt(String message, String key) throws Exception {

 

        byte[] bytesrc = decodeBase64(message);//convertHexString(message);

        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.DECRYPT_MODE, secretKey, iv);

 

        byte[] retByte = cipher.doFinal(bytesrc);

        return new String(retByte);

    }

 

    public static byte[] convertHexString(String ss) {

        byte digest[] = new byte[ss.length() / 2];

        for (int i = 0; i < digest.length; i++) {

            String byteString = ss.substring(2 * i, 2 * i + 2);

            int byteValue = Integer.parseInt(byteString, 16);

            digest[i] = (byte) byteValue;

        }

 

        return digest;

    }

 

    public static String toHexString(byte b[]) {

        StringBuffer hexString = new StringBuffer();

        for (int i = 0; i < b.length; i++) {

            String plainText = Integer.toHexString(0xff & b[i]);

            if (plainText.length() < 2)

                plainText = "0" + plainText;

            hexString.append(plainText);

        }

 

        return hexString.toString();

    }

 

     

    public static String encodeBase64(byte[] b) {

        return Base64.encodeToString(b, Base64.DEFAULT);

    }

     

    public static byte[] decodeBase64(String base64String) {

        return Base64.decode(base64String, Base64.DEFAULT);

    }

}


上一篇:C#经验总结

下一篇:VS Studio配置错误时

Top