您现在的位置是:网站首页> C#技术
Golang、PHP、Java、C#、ObjectC互通DES加密与解密
- C#技术
- 2022-08-20
- 17472人已阅读
在完成一个大项目时候,我们要用到多语言来开发接口,每个模块可能分配到各小组中,各小组成员用到语言往往不一样,在向接口传递参数的时候,就要用到加密与解密。
在网上找了一些,这篇文章中有通用的写法,《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配置错误时