2017-05-30 34 views
0

我需要使用3DES和PKCS7填充(用靜態鍵和IV)到Ruby或Python的C#加密/解密類,但似乎輸出是完全不同。C#TripleDES CBC/PKCS7 /十六進制不等於Ruby/Python TripleDES

這裏是代碼的C#代碼片段:

public CryptoDES3() 
{ 
    this.objCryptoProvider = new TripleDESCryptoServiceProvider(); 
    this.CipherMode = CipherMode.CBC; 
    this.PaddingMode = PaddingMode.PKCS7; 
    this.EncodingType = CryptoDES3.EncodingTypeEnum.Hex; 
} 

/* ----- */ 

public string Encrypt(string strValue, string strKey, string strIV, CryptoDES3.EncodingTypeEnum intEncodingType) 
{ 
    string str = ""; 
    if (strValue.Length > 0) 
    { 
    this.objCryptoProvider.Mode = this.CipherMode; 
    this.objCryptoProvider.Padding = this.PaddingMode; 
    byte[] bytes1 = Encoding.Default.GetBytes(CryptoDES3.HexDecode(strKey)); 
    byte[] bytes2 = Encoding.Default.GetBytes(CryptoDES3.HexDecode(strIV)); 
    MemoryStream memoryStream = new MemoryStream(); 
    CryptoStream cryptoStream = new CryptoStream((Stream) memoryStream, this.objCryptoProvider.CreateEncryptor(bytes1, bytes2), CryptoStreamMode.Write); 
    StreamWriter streamWriter = new StreamWriter((Stream) cryptoStream); 
    streamWriter.Write(strValue); 
    streamWriter.Flush(); 
    cryptoStream.FlushFinalBlock(); 
    string strValue1 = Encoding.Default.GetString(memoryStream.GetBuffer(), 0, checked ((int) memoryStream.Length)); 
    switch (intEncodingType) 
    { 
     case CryptoDES3.EncodingTypeEnum.Hex: 
     str = CryptoDES3.HexEncode(strValue1); 
     break; 
     case CryptoDES3.EncodingTypeEnum.Base64: 
     str = CryptoDES3.Base64Encode(strValue1); 
     break; 
     default: 
     str = strValue1; 
     break; 
    } 
    } 
    return str; 
} 

public string Decrypt(string strValue, string strKey, string strIV, CryptoDES3.EncodingTypeEnum intEncodingType) 
{ 
    string str = ""; 
    if (strValue.Length > 0) 
    { 
    this.objCryptoProvider.Mode = this.CipherMode; 
    this.objCryptoProvider.Padding = this.PaddingMode; 
    byte[] bytes1 = Encoding.Default.GetBytes(CryptoDES3.HexDecode(strKey)); 
    byte[] bytes2 = Encoding.Default.GetBytes(CryptoDES3.HexDecode(strIV)); 
    string s; 
    switch (intEncodingType) 
    { 
     case CryptoDES3.EncodingTypeEnum.Hex: 
     s = CryptoDES3.HexDecode(strValue); 
     break; 
     case CryptoDES3.EncodingTypeEnum.Base64: 
     s = CryptoDES3.Base64Decode(strValue); 
     break; 
     default: 
     s = strValue; 
     break; 
    } 
    str = new StreamReader((Stream) new CryptoStream((Stream) new MemoryStream(Encoding.Default.GetBytes(s)), this.objCryptoProvider.CreateDecryptor(bytes1, bytes2), CryptoStreamMode.Read)).ReadToEnd(); 
    } 
    return str; 
} 

/* ----- */ 

internal const string DES3_KEY = "A0498F07C46808173894BB976F9726477CC0913D87DE912A"; 
internal const string DES3_IV = "0A9B11D6FEE830A9"; 

這裏是Ruby代碼與它的輸出到控制檯:

#!/usr/bin/env ruby 
require 'digest' 
require 'openssl' 

ALG = "DES-EDE3-CBC" 
KEY = "\xA0\x49\x8F\x07\xC4\x68\x08\x17\x38\x94\xBB\x97\x6F\x97\x26\x47\x7C\xC0\x91\x3D\x87\xDE\x91\x2A" 
IV = "\x0A\x9B\x11\xD6\xFE\xE8\x30\xA9" 

def encode(data) 
    cipher = OpenSSL::Cipher::Cipher.new(ALG) 
    cipher.key = KEY 
    cipher.iv = IV 
    cipher.encrypt 
    result = cipher.update(data) 
    result << cipher.final 
    result = result.unpack('H*') 
end 

def decode(data) 
    cipher = OpenSSL::Cipher::Cipher.new(ALG) 
    cipher.key = KEY 
    cipher.iv = IV 
    cipher.decrypt 
    data = data.pack('H*') 
    result = cipher.update(data) 
    result << cipher.final 
end 

data = "test" 

encoded = encode(data) 
decoded = decode(encoded) 

puts "Encrypted: #{encoded[0]}" 
puts "Decrypted: #{decoded}" 

輸出:

$ ./3des.rb 
Encrypted: 33fd6ee287c0f46f 
Decrypted: test 

Python代碼:

#!/usr/bin/env python 
import pyDes 

k = pyDes.triple_des('A0498F07C46808173894BB976F9726477CC0913D87DE912A'.decode('hex'), mode=pyDes.CBC, IV="0A9B11D6FEE830A9".decode('hex'), pad=None, padmode=pyDes.PAD_PKCS5) 
d = k.encrypt("test") 

print "Encrypted: " + d.encode('hex') 

print "Decrypted: " + k.decrypt(d) 

輸出:使用chilkat.CkCrypt2()在Python

$ ./3des.py 
Encrypted: 33fd6ee287c0f46f 
Decrypted: test 

相同的輸出。

MS C#TripleDESCryptoServiceProvider()與Ruby,Python,OpenSSL有所不同嗎? 任何想法我怎麼能得到相同的結果?

+1

哪裏是你的C#輸出? –

+0

無法制作C#單機加密/解密二進制文件,我不知道任何C# – bsteo

+1

也許你應該對此做一個速度過程,因爲這可能也意味着你不知道如何調試。我們不是來幫你解決這個問題的。 –

回答

0

它製造的C#也行:

using Microsoft.VisualBasic; 
using Microsoft.VisualBasic.CompilerServices; 
using System; 
using System.IO; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Security.Cryptography; 
using System.Threading.Tasks; 

namespace _3DES 
{ 
    class Program 
    { 

     public static string Encrypt(string strValue) 
     { 
      const string DES3_KEY = "A0498F07C46808173894BB976F9726477CC0913D87DE912A"; 
      const string DES3_IV = "0A9B11D6FEE830A9"; 
      TripleDESCryptoServiceProvider objCryptoProvider; 
      string str = ""; 
      if (strValue.Length > 0) 
      { 
       objCryptoProvider = new TripleDESCryptoServiceProvider(); 
       objCryptoProvider.Mode = CipherMode.CBC; 
       objCryptoProvider.Padding = PaddingMode.PKCS7; 
       byte[] bytes1 = Encoding.Default.GetBytes(HexDecode(DES3_KEY)); 
       byte[] bytes2 = Encoding.Default.GetBytes(HexDecode(DES3_IV)); 
       MemoryStream memoryStream = new MemoryStream(); 
       CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, objCryptoProvider.CreateEncryptor(bytes1, bytes2), CryptoStreamMode.Write); 
       StreamWriter streamWriter = new StreamWriter((Stream)cryptoStream); 
       streamWriter.Write(strValue); 
       streamWriter.Flush(); 
       cryptoStream.FlushFinalBlock(); 
       string strValue1 = Encoding.Default.GetString(memoryStream.GetBuffer(), 0, checked((int)memoryStream.Length)); 
       str = HexEncode(strValue1); 
      } 
      return str; 
     } 

     public static string Decrypt(string strValue) 
     { 
      const string DES3_KEY = "A0498F07C46808173894BB976F9726477CC0913D87DE912A"; 
      const string DES3_IV = "0A9B11D6FEE830A9"; 
      TripleDESCryptoServiceProvider objCryptoProvider; 
      string str = ""; 
      if (strValue.Length > 0) 
      { 
       objCryptoProvider = new TripleDESCryptoServiceProvider(); 
       objCryptoProvider.Mode = CipherMode.CBC; 
       objCryptoProvider.Padding = PaddingMode.PKCS7; 
       byte[] bytes1 = Encoding.Default.GetBytes(HexDecode(DES3_KEY)); 
       byte[] bytes2 = Encoding.Default.GetBytes(HexDecode(DES3_IV)); 
       string s; 
       s = HexDecode(strValue); 
       str = new StreamReader((Stream)new CryptoStream((Stream)new MemoryStream(Encoding.Default.GetBytes(s)), objCryptoProvider.CreateDecryptor(bytes1, bytes2), CryptoStreamMode.Read)).ReadToEnd(); 
      } 
      return str; 
     } 

     public static string HexEncode(string strValue) 
     { 
      string str = ""; 
      if (strValue.Length > 0) 
      { 
       byte[] bytes = Encoding.Default.GetBytes(strValue); 
       int num = 0; 
       int upperBound = bytes.GetUpperBound(0); 
       int index = num; 
       while (index <= upperBound) 
       { 
        str += Conversion.Hex(bytes[index]).PadLeft(2, '0'); 
        checked { ++index; } 
       } 
      } 
      return str; 
     } 

     public static string HexDecode(string strValue) 
     { 
      string str = ""; 
      if (strValue.Length > 0) 
      { 
       strValue = strValue.ToUpper(); 
       int num1 = 0; 
       int num2 = checked(strValue.Length - 2); 
       int startIndex = num1; 
       while (startIndex <= num2) 
       { 
        str += Conversions.ToString(Strings.Chr(Conversions.ToInteger("&H" + strValue.Substring(startIndex, 2)))); 
        checked { startIndex += 2; } 
       } 
      } 
      return str; 
     } 

     static void Main(string[] args) 
     { 
      String encoded = Encrypt("test"); 
      Console.WriteLine(encoded); 
      String plain = Decrypt(encoded); 
      Console.WriteLine(plain); 
     } 
    } 
} 

輸出:

C:\> 3DES.exe 
33FD6EE287C0F46F 
test