6

Salesforceで次のApexコードを実行して、文字列を暗号化します。

public static String getEncryptedData() { 
    Blob cryptoKey = Crypto.generateAesKey(256);  

    String dataToEncrypt =  'Test string';                                  

    Blob encryptedData = Crypto.encryptWithManagedIV('AES256', cryptoKey, Blob.valueOf(dataToEncrypt));  

    return EncodingUtil.base64Encode(encryptedData);
}

この実装が正しいと仮定すると、C#で復号化する必要があります。次のようなものがありますが、「パディングが無効で削除できません」というエラーが表示されます。(もちろん、サンプルキーと暗号化された文字列値):

private string Decrypt(string encryptedbase64Password)
{
    RijndaelManaged aes256 = new RijndaelManaged();
    aes256.KeySize = 256;
    aes256.Mode = CipherMode.CBC;
    aes256.Padding = PaddingMode.PKCS7;
    aes256.BlockSize = 128;

    // Salesforce.com stores the first 16 bytes as the IV
    // Extract first 16 bytes as IV, the rest as the Key
    string keyAndIv = "Ii7oSjjWuhp6J6/hj/wmivqx1h3N2HzJ2ByJOy1n89E="; // sample from SFDC
    // hard coded for this example:
    encryptedbase64Password = "hRVlbM79aEQi8Tz7JJIL7CEhSxZAJvCh8Ni6ORP1C55+qbJzjDshBYBjyP12/zT2";
    byte[] allBytes = Convert.FromBase64String(keyAndIv);
    byte[] iv = new byte[16];
    Array.Copy(allBytes, 0, iv, 0, iv.Length);
    byte[] key = new byte[allBytes.Length - 16];
    Array.Copy(allBytes, 16, key, 0, key.Length);

    aes256.Key = key;
    aes256.IV = iv;

    ICryptoTransform decrypto = aes256.CreateDecryptor();
    byte[] encryptedbytes = Convert.FromBase64String(encryptedbase64Password);
    byte[] decryptedText = decrypto.TransformFinalBlock(encryptedbytes, 0, encryptedbytes.Length);
    string result = Convert.ToBase64String(decryptedText);

    return result;
}

私は何が間違っているのですか?

4

1 に答える 1

6

ユーザー「Doublehead Software」は、Salesforce 開発者ボードに正しい解決策を投稿しました。CryptoStream がパディングの問題を正しく処理しているように見えます。完全な解決策:

string plaintext;
byte[] Key = Convert.FromBase64String("Ii7oSjjWuhp6J6/hj/wmivqx1h3N2HzJ2ByJOy1n89E=");
string encryptedbase64Password = "hRVlbM79aEQi8Tz7JJIL7CEhSxZAJvCh8Ni6ORP1C55+qbJzjDshBYBjyP12/zT2";
byte[] IV = new byte[16];
byte[] phase = Convert.FromBase64String(encryptedbase64Password);
Array.Copy(phase, 0, IV, 0, IV.Length);
byte[] cipherText = new byte[phase.Length - 16];;
Array.Copy(phase, 16, cipherText, 0, cipherText.Length);

using (AesManaged aesAlg = new AesManaged())
{
    aesAlg.KeySize = 256;
    aesAlg.Mode = CipherMode.CBC;
    aesAlg.Padding = PaddingMode.PKCS7;
    aesAlg.Key = Key;
    aesAlg.IV = IV;
    // Create a decryptor to perform the stream transform.
    // NOTE: This is the difference between my original solution and the correct one.
    ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
    // Create the streams used for decryption.
    using (MemoryStream msDecrypt = new MemoryStream(cipherText))
    {
        using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
        {
            using (StreamReader srDecrypt = new StreamReader(csDecrypt))
            {
                // Read the decrypted bytes from the decrypting stream and place them in a string.
                plaintext = srDecrypt.ReadToEnd();
            }
        }
    }
}
于 2013-03-14T14:32:06.263 に答える