TripleDES no modo CFB, C # e Crypto ++ difere

Aqui está o meu problema: Eu tenho um código legado em C ++ (usando o crypto ++ v5.6.1) e desenvolvo um novo em C # (.NET 3.5 usando System.Security.Cryptography). Eunão pode mudar o código C ++, mas eu preciso ser capaz de descriptografar dados criptografados anteriormente e aplicativos anteriores tem que ser capaz de descriptografar os dados que vou criptografar com o meu novo código c #.

O algoritmo usado é TripleDES com o modo de cifra CFB em ambos os casos, mas no final, os dados criptografados não são os mesmos, o número de bytes é idêntico, assim como o primeiro byte, mas além disso todos os outros bytes são diferentes.

O preenchimento é feito manualmente (adicionando zeros) no código C ++. Então eu defino o PaddingValue para PaddingMode.Zeros. (Eu também tentei adicionar zeros no final manualmente no código C #, isso não mudou nada).

Eu tentei usar System.Text.Encoding diferente, mas o resultado é o mesmo (na verdade, os caracteres testados são ASCII "puro" (por exemplo, entre 0 e 126)).

O valor do MandatoryBlockSize (), no código C ++, é 8, então eu configurei o FeedbackSize para 8 também. Mas se eu entendi escrever, é na verdade o tamanho do meu IV, não é?

O tamanho da chave é de 24 bytes (3 chaves diferentes) e o IV tem 8 bytes de comprimento. Eles são os mesmos nos dois códigos.

Se eu usar o modo CBC, em ambos os casos, os resultados são os mesmos (mas, como eu disse, não posso alterar o código legado ...), o modo OFB & CTS gera exceções (indisponível para um e incompatível para o outro) no meu aplicativo .NET, não posso comparar os resultados.

Eu tentei usar Mono, com .net versões 3.5 e 4.0, ou usando visual, com .net 3.5 ou 4.0, e os 4 resultados criptografados são os mesmos, mas difere do resultado original.

Agora eu realmente não sei o que testar ... Eu prefiro não envolver o Crypto ++ em um projeto C ++ / CLI para usá-lo em vez do System.Security.Cryptography.

Alguém tem um conselho ou pode dizer o que estou fazendo errado?

Aqui está o código C ++:

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;
}

Aqui está o código C #:

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: Eu tentei usar o Encryptor diretamente, em vez de usar os fluxos e eu tenho o mesmo problema.

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;
}

questionAnswers(2)

yourAnswerToTheQuestion