2012-08-10 138 views
1

我有一個IV(初始化向量)和關鍵,我需要CYPHER一個字符串,這是代碼:密碼Rijndael算法德爾福2010 DCP

function TForm1.CipherAES (key: AnsiString; Vector: AnsiString; 
    InStream: TMemoryStream) : TMemoryStream; 
var 
    cipher: TDCP_rijndael; 
    i: integer; 
    toEnc, toSnd : array of byte; 
    outStream, AStream :TMemoryStream; 
    StreamR, Stream2 : AnsiString; 
begin 
    outStream := TMemoryStream.Create; 
    SetLength(toEnc, InStream.Size); 

    cipher := TDCP_rijndael.Create(nil); 
    cipher.Init(key[1], 128, nil); 
    cipher.SetIV(vector[1]); 
    cipher.BlockSize := 16; 
    InStream.Position := 0; 

    for I := 0 to InStream.Size-1 do 
    InStream.Read(ToEnc[i], 1); 

    for I := 0 to inStream.size-1 do 
    StreamR := StreamR + ByteToHex(toEnc[i]) + ' '; 
    Memo1.Lines.Add(StreamR); 
    inStream.Position := 0; 

    cipher.CipherMode := cmCBC; 
    cipher.EncryptStream(inStream, outStream, InStream.Size); 
    Base64Encode(outStream.Memory, @StreamR[1], outStream.Size); 

    Stream2 := Copy(StreamR, 1, outStream.Size + 8); 
    Memo1.Lines.Add(Stream2); 
    Memo1.Lines.Add(StreamR); 

    outStream.Position := 0; 

    SetLength(toSnd, outStream.Size); 
    for I := 0 to outStream.Size-1 do 
    outStream.Read(toSnd[i], 1); 

    StreamR := ''; 
    for I := 0 to outStream.size-1 do 
    StreamR := StreamR + ByteToHex(toSnd[i]) + ' '; 
    Memo1.Lines.Add(StreamR); 

    cipher.burn; 
    cipher.free; 

    Result := outStream; 
end; 

當我通過流爲base64給我的下一個答案:

ub/JkCsCZwbAnyqjo+miIw== 

,但它應該是:

ub/JkCsCZwbAnyqjo+miI2XNZwNrJo31YBNTwQuHkq0= 

有人能幫助我嗎?爲什麼會發生這樣的事情?

在此先感謝 Vauli

回答

1

如果您的base64解碼這兩個值,你會得到:

UB/JkCsCZwbAnyqjo + miIw ==解碼爲:

B9 BF C9 90 2B 02 67 06-C0 9F 2A A3 A3 E9 A2 23 (in hex) 

=> 16個字節

ub/JkCsCZwbAnyqjo + miI2XNZwNrJo31YBNTwQuHkq0 =解碼爲:

B9 BF C9 90 2B 02 67 06-C0 9F 2A A3 A3 E9 A2 23 
65 CD 67 03 6B 26 8D F5-60 13 53 C1 0B 87 92 AD (in hex) 

=> 32字節

這讓我覺得你逝去的只有16字節到TForm1.CipherAES()。 我是說,因爲在調用cipher.EncryptStream之後,outStream.size應該等於inStream.size

請在使用斷點測試時澄清InStream.Size的值。

您的代碼的一些注意事項:

  1. Base64Encode返回輸出緩衝區包含的字節數。 您從不使用此值來設置StreamR的大小。

    您對base64encode調用應該是這樣的:

    // Allocate buffer for base64 decoded data 
    setLength(StreamR, ((inStrem.size + 2) div 3) * 4); 
    size := Base64Encode(outStream.Memory, @StreamR[1], outStream.Size); 
    setLength(StreamR, size); 
    
  2. 我真的不明白這是什麼意思:

    流2:=複製(StreamR,1, outStream.Size + 8 );

    爲什麼outStream.Size + 8?您正在根據其他緩衝區的大小從StreamR複製一些東西, ,無視您的StreamR的實際大小?另外「Copy()」只能獲得最多的LENGTH(StreamR)字符。

  3. 代替通過字節填充字節ToEnc的考慮使用:

    InStream.ReadBuffer(ToEnc [0],InStream.size);

    toSnd(但是。writeBuffer())


注意有關加密字符串(因爲我不知道你是怎麼喂插播廣告):

確保你加密文本的Unicode版本(UTF16- LE或UTF-8)。將字符串轉換爲ansiString將通過OS系統語言環境進行,並可導致數據丟失(着名的'????')

+0

感謝您的回答,其值如下: – vauli 2012-08-13 15:22:50

+0

ok大小inStream是16字節,表示我的密碼運行良好,我必須通過32個字節來獲得我需要的32個字節。另一方面,我會根據你的建議使用base64encode的輸出,Stream2部分只是顯示編碼的結果(這很愚蠢,我知道),我會嘗試填充數組,我會告訴你一切是否順利。謝謝..!!! – vauli 2012-08-13 15:50:28

+0

他們告訴我,32個Byets是從PKCS7填充 – vauli 2012-08-13 16:23:06