TripleDES im CFB-Modus, C # und Crypto ++ sind unterschiedlich

Hier ist mein Problem: Ich habe einen älteren Code in C ++ (unter Verwendung von Crypto ++ v5.6.1) und ich entwickle einen neuen in C # (.NET 3.5 unter Verwendung von System.Security.Cryptography). ichkann mich nicht ändern der C ++ - Code, aber ich muss in der Lage sein, zuvor verschlüsselte Daten zu entschlüsseln, und frühere Anwendungen müssen in der Lage sein, die Daten zu entschlüsseln, die ich mit meinem neuen C # -Code verschlüsseln werde.

Der verwendete Algorithmus ist in beiden Fällen TripleDES mit CFB-Verschlüsselungsmodus, aber am Ende sind die verschlüsselten Daten nicht gleich, die Anzahl der Bytes ist identisch sowie das erste Byte, aber ansonsten sind alle anderen Bytes unterschiedlich.

Das Auffüllen erfolgt manuell (Hinzufügen von Nullen) im C ++ - Code. Also habe ich den PaddingValue auf PaddingMode.Zeros gesetzt. (Ich habe auch versucht, am Ende manuell Nullen in den C # -Code einzufügen, es hat sich nichts geändert).

Ich habe versucht, verschiedene System.Text.Encoding zu verwenden, aber das Ergebnis ist das gleiche (tatsächlich sind die getesteten Zeichen "reines" ASCII (d. H. Zwischen 0 und 126)).

Der Wert von MandatoryBlockSize () im C ++ - Code ist 8, daher setze ich auch FeedbackSize auf 8. Aber wenn ich es so verstehe, hat es tatsächlich die Größe meiner Infusion, oder?

Die Schlüsselgröße beträgt 24 Bytes (3 verschiedene Schlüssel) und die Länge des IV beträgt 8 Bytes. Sie sind beide in den 2 Codes gleich.

Wenn ich stattdessen den CBC-Modus verwende, sind die Ergebnisse in beiden Fällen gleich (aber wie gesagt, ich kann den alten Code nicht ändern ...). Im OFB- und CTS-Modus werden Ausnahmen ausgelöst (für die eine nicht verfügbar und für die andere nicht kompatibel). In meiner .NET-Anwendung kann ich keine Ergebnisse vergleichen.

Ich habe versucht, Mono mit .Net-Versionen 3.5 und 4.0 oder Visual mit .Net 3.5 oder 4.0 zu verwenden, und die 4 verschlüsselten Ergebnisse sind dieselben, unterscheiden sich jedoch vom ursprünglichen Ergebnis.

Jetzt weiß ich wirklich nicht, was ich testen soll ... Ich würde Crypto ++ lieber nicht in ein C ++ / CLI-Projekt einbinden, um es anstelle von System.Security.Cryptography zu verwenden.

Hat jemand einen Rat oder kann er sagen, was ich falsch mache?

Hier ist der C ++ Code:

void *CryptData(BYTE *bDataIn, LONG lIn, LONG *lOut, byte* key, byte* iv)
{
    byte    *bIn;
    byte    *bOut;
    LONG    l2,lb;

    CFB_FIPS_Mode<DES_EDE3>::Encryption encryption_DES_EDE3_CFB;
    encryption_DES_EDE3_CFB.SetKeyWithIV(key, sizeof(key), iv, sizeof(iv));

    lb = encryption_DES_EDE3_CFB.MandatoryBlockSize();
    l2 = ((lIn + lb - 1)/lb)*lb;

    bIn = (byte*)malloc(l2);
    bOut = (byte*)malloc(l2);

    memset(bIn,0,l2);
    memset(bOut,0,l2);
    memcpy(bIn,bDataIn,lIn);

    encryption_DES_EDE3_CFB.ProcessString(bOut, bIn, l2);

    *lOut = l2;

    return bOut;
}

Hier ist der C # -Code:

public FibxCrypt()
{
    _cryptoAlgo = new TripleDESCryptoServiceProvider();
    //_cryptoAlgo.GenerateKey();
    _cryptoAlgo.Key = _key;
    //_cryptoAlgo.GenerateIV();
    _cryptoAlgo.IV = _iv;
    _cryptoAlgo.Mode = CipherMode.CFB;
    _cryptoAlgo.Padding = PaddingMode.Zeros;

    _encoding = new UTF8Encoding();
}

private MemoryStream EncryptingString(string plainText, out long encryptSize)
{
    // Check arguments. 
    if (plainText == null || plainText.Length <= 0)
        throw new ArgumentNullException("plainText");

    // Create a decrytor to perform the stream transform.
    ICryptoTransform encryptor = _cryptoAlgo.CreateEncryptor();

    // Create the streams used for encryption. 
    //using (MemoryStream msEncrypt = new MemoryStream())
    MemoryStream msEncrypt = new MemoryStream();

    encryptSize = ((plainText.Length + _cryptoAlgo.FeedbackSize - 1) / _cryptoAlgo.FeedbackSize) * _cryptoAlgo.FeedbackSize;

    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
    {
        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt, _encoding))
        {
            //Write all data to the stream.
            swEncrypt.Write(plainText);
        }
    }

    // Return the encrypted memory stream. 
    return msEncrypt;
}

EDIT: Ich habe versucht, den Encryptor direkt zu verwenden, anstatt die Streams zu verwenden, und ich habe das gleiche Problem.

private MemoryStream EncryptingString(string plainText, out long encryptSize)
{
    // Check arguments. 
    if (plainText == null || plainText.Length <= 0)
        throw new ArgumentNullException("plainText");

    ICryptoTransform encryptor = _cryptoAlgo.CreateEncryptor();

    byte[] cipherData = encryptor.TransformFinalBlock(
        _encoding.GetBytes(plainText), 0, plainText.Length);

    // Return the encrypted memory stream. 
    return msEncrypt;
}

Antworten auf die Frage(2)

Ihre Antwort auf die Frage