2017-04-07 7 views
2

C# 값을 암호화 한 다음 고전적인 ASP에서 해독해야합니다. 이 일을하는 데 가장 가까운 것은 복어와 같습니다. 그러나 문제는 두 가지 구현이 약간 다른 결과를 생성하고 왜 그런지 확신 할 수 없다는 것입니다. 사용Blowfish C#과 Classic ASP의 결과가 다릅니다

구현 :

C 번호 : https://defuse.ca/blowfish.htm

VBScript를 : http://www.di-mgt.com.au/cryptoBlowfishASP.html

C# 코드 :

var input = "Hello World"; 
var key = "04B915BA43FEB5B6"; 
BlowFish b = new BlowFish(key); 

string enc, dec; 

enc = b.Encrypt_ECB(input); 
dec = b.Decrypt_ECB(enc); 

VBScript를 :

Dim aKey() 
Dim nKeyLen, szTxtKey, szTxtPlain, szTxtKeyAsString, szTxtCipher, szTxtCipherHex, szTxtCipher64, szTxtDecrypt 

szTxtKey = "04B915BA43FEB5B6" 
szTxtPlain = "Hello World" 

ReDim aKey((Len(szTxtKey) \ 2) - 1) 
nKeyLen = bu_HexStr2Bytes(szTxtKey, aKey) 
Call blf_Key(aKey, nKeyLen) 
szTxtKeyAsString = bu_Bytes2HexStr(aKey, nKeyLen) 

szTxtCipher = blf_StringEnc(szTxtPlain) 
szTxtCipherHex = bu_Str2Hex(szTxtCipher) 

C#을 출력 :

819dd50a925a5eb83ed723bea6d84984 

VBScript를 출력 :

819DD50A925A5EB8CABE974A654A18A8 

출력의 첫 번째 절반은 동일합니다 : 나는 VBScript를 암호를 해독하면 "819DD50A925A5EB8"

재미있는 것은,이다 C# 라이브러리의 출력 결과 : Hello World ♣♣♣♣♣

그래서 ... 거의 작동하지만 일종의 패딩이나 뭔가가 진행 중입니다. 나는 이것을 고치는 방법을 모른다.

+2

다른 패딩 : https://en.wikipedia.org/wiki/Padding_(cryptography) –

+0

@ArtjomB. 그것은 내가 생각하고있는 것입니다. 두 가지 구현이 호환되지 않으며, 둘 중 하나를 다시 작성하거나 변경하지 않고 함께 사용할 수있는 방법이 없다는 뜻입니까? – FirstDivision

+0

최악의 경우에는 코드에서 패딩을 해결할 수 있습니다. 그러나 Blowfish를 사용하지 마십시오. 구식입니다. 작성자가 이제 AES를 사용합니다. AES는 Blowfish보다 사용하기가 더 이상 안전하지 않으며 더 안전합니다. – zaph

답변

2

@artjom-balready mentioned in the comments이므로, 다른 패딩이 발생합니다.

다른 패딩 방법에 대한 좋은 설명이 here입니다.

blowfish.cs 파일을 분석하면 NULL 패딩 을 사용하고 있음을 알 수 있습니다 (파일의 코드 조각에 유의하십시오); 이에

/// <summary> 
/// Decrypts a string (ECB) 
/// </summary> 
/// <param name="ct">hHex string of the ciphertext</param> 
/// <returns>Plaintext ascii string</returns> 
public string Decrypt_ECB(string ct) 
{ 
    return Encoding.ASCII.GetString(Decrypt_ECB(HexToByte(ct))).Replace("\0", ""); 
} 

고전 ASP 구현 PKCS5 패딩 사용 (basBlowfishFns.asp에서 니펫 도시 PKCS5 법)

바이트 Using Padding in Encryption
패드로부터 개수와 같은 값의 모든 패딩 바이트 수 (PKCS5 패딩)

' Get # of padding bytes from last char 
nPad = Asc(Right(strData, 1)) 
If nPad > 8 Then nPad = 0 ' In case invalid 
strData = Left(strData, nLen - nPad) 

해결 방법은 C# 라이브러리에서 사용하는 NULL 채우기에 대한 대안을 적용하는 것입니다.

여기에 수정 된 basBlowfishFns.asp(수정 된 기능 만 표시);

Public Function blf_StringEnc(strData, padMethod) 
' Encrypts plaintext strData after adding RFC 2630 padding 
' Returns encrypted string. 
' Requires key and boxes to be already set up. 
' Version 5. Completely revised. 
' The speed improvement here is due to Robert Garofalo. 
    Dim strIn 
    Dim strOut 
    Dim nLen 
    Dim sPad 
    Dim nPad 
    Dim nBlocks 
    Dim i 
    Dim j 
    Dim aBytes(7) 
    Dim sBlock 
    Dim iIndex 

    ' Pad data string to multiple of 8 bytes 
    strIn = PadString(strData, padMethod) 
    ' Calc number of 8-byte blocks 
    nLen = Len(strIn) 
    nBlocks = nLen \ 8 
    ' Allocate output string here so we can use Mid($ below 
    ' strOut = String(nLen, " ") 
    strOut = ""  ' Fix for VBScript 

    ' Work through string in blocks of 8 bytes 
    iIndex = 0 
    For i = 1 To nBlocks 
     sBlock = Mid(strIn, iIndex + 1, 8) 
     ' Convert to bytes 
     ' aBytes() = StrConv(sBlock, vbFromUnicode) 
     Call bu_String2Bytes(sBlock, aBytes) 
     ' Encrypt the block 
     Call blf_EncryptBytes(aBytes) 
     ' Convert back to a string 
     ' sBlock = StrConv(aBytes(), vbUnicode) 
     sBlock = bu_Bytes2String(aBytes, 8) 
     ' Copy to output string 
     ' Mid(strOut, iIndex + 1, 8) = sBlock 
     strOut = strOut & sBlock 
     iIndex = iIndex + 8 
    Next 

    blf_StringEnc = strOut 

End Function 

Public Function blf_StringDec(strData, padMethod) 
' Decrypts ciphertext strData and removes RFC 2630 padding 
' Returns decrypted string. 
' Requires key and boxes to be already set up. 
' Version 5. Completely revised. 
' The speed improvement here is due to Robert Garofalo. 
    Dim strIn 
    Dim strOut 
    Dim nLen 
    Dim sPad 
    Dim nPad 
    Dim nBlocks 
    Dim i 
    Dim j 
    Dim aBytes(7) 
    Dim sBlock 
    Dim iIndex 

    strIn = strData 
    ' Calc number of 8-byte blocks 
    nLen = Len(strIn) 
    nBlocks = nLen \ 8 
    ' Allocate output string here so we can use Mid($ below 
    'strOut = String(nLen, " ") 
    strOut = "" 

    ' Work through string in blocks of 8 bytes 
    iIndex = 0 
    For i = 1 To nBlocks 
     sBlock = Mid(strIn, iIndex + 1, 8) 
     ' Convert to bytes 
     ' aBytes() = StrConv(sBlock, vbFromUnicode) 
     Call bu_String2Bytes(sBlock, aBytes) 
     ' Encrypt the block 
     Call blf_DecryptBytes(aBytes) 
     ' Convert back to a string 
     'sBlock = StrConv(aBytes(), vbUnicode) 
     sBlock = bu_Bytes2String(aBytes, 8) 
     ' Copy to output string 
     ' Mid(strOut, iIndex + 1, 8) = sBlock 
     strOut = strOut & sBlock 
     iIndex = iIndex + 8 
    Next 

    ' Strip padding, if valid 
    strOut = UnpadString(strOut, padMethod) 

    blf_StringDec = strOut 

End Function 

Public Function PadString(strData, method) 
' Pad data string to next multiple of 8 bytes as per RFC 2630 
    Dim nLen 
    Dim sPad 
    Dim nPad 
    nLen = Len(strData) 
    nPad = ((nLen \ 8) + 1) * 8 - nLen 
    Select Case method 
    Case "PKCS5" 
     sPad = String(nPad, Chr(nPad)) ' Pad with # of pads (1-8) 
    Case "NULL" 
     sPad = String(nPad, Chr(0)) ' Pad with # of NULL characters 
    End Select 
    PadString = strData & sPad 

End Function 

Public Function UnpadString(strData, method) 
' Strip RFC 2630-style padding 
    Dim nLen 
    Dim nPad 
    nLen = Len(strData) 
    If nLen = 0 Then Exit Function 
    Select Case method 
    Case "PKCS5" 
     ' Get # of padding bytes from last char 
     nPad = Asc(Right(strData, 1)) 
     If nPad > 8 Then nPad = 0 ' In case invalid 
     strData = Left(strData, nLen - nPad) 
    Case "NULL" 
     'Remove any NULL characters, obviously, this method isn't ideal if 
     'the data contains valid NULLs. This shouldn't be an issue with 
     'ASCII text. 
     strData = Replace(strData, Chr(0), "") 
    End Select 
    UnpadString = strData 
End Function 

키 변형 PadString()UnpadString() 기능한다. method 매개 변수를 추가하여 NULL 또는 PKCS5 식별자를 전달하여 데이터 패드/패딩 방식을 결정할 수 있습니다. 이러한 기능은 이미 존재하지만 어떤 이유로 인해 blf_StringEnc()blf_StringDec() 기능에 사용되지 않았으므로 DRY principle의 이익을 위해 사용되도록 수정했습니다.

(코드를 좀 더 유연하게 만들 때 빠른 찌르기) 다음 코드를 사용하십시오.

Dim aKey() 
Dim nKeyLen, szTxtKey, szTxtPlain, szTxtKeyAsString, szTxtCipher, szTxtCipherHex, szTxtCipher64, szTxtDecrypt 

szTxtKey = "04B915BA43FEB5B6" 
szTxtPlain = "Hello World" 

ReDim aKey((Len(szTxtKey) \ 2) - 1) 
nKeyLen = bu_HexStr2Bytes(szTxtKey, aKey) 
Call blf_Key(aKey, nKeyLen) 
szTxtKeyAsString = bu_Bytes2HexStr(aKey, nKeyLen) 

'Encrypt using NULL padding method. 
szTxtCipher = blf_StringEnc(szTxtPlain, "NULL") 
szTxtCipherHex = bu_Str2Hex(szTxtCipher) 

Call Response.Write(szTxtCipherHex) 

결과가;

819DD50A925A5EB83ED723BEA6D84984 

원래 예상대로.

+0

훌륭한 응답, 설명 및 솔루션을 제공해 주셔서 감사합니다! – FirstDivision

2

VBScript에서 명령 줄로 내보낼 수있는 경우 문자열을 암호화하는 동일한 C# 라이브러리를 사용하여 콘솔 응용 프로그램을 만들 수 있습니다. 약간의 문제 해결 방법이지만 동일한 라이브러리를 사용하게 될 것입니다.