簡體   English   中英

Java中的C#加密實現

[英]C# encryption realization in java

我正在開發一個Android應用程序,在其中我需要實現一些加密。 同時,我必須保持與其他已在生產中的應用程序版本(例如WP平台)的兼容性。

這是C#代碼:

static public byte[] Encrypt(String passphrase, byte[] data)
    {
        //encrypted data
        byte[] buffer = null;

        //crypto handles
        IntPtr hProvider = IntPtr.Zero;
        IntPtr hKey = IntPtr.Zero;

        try
        {

            if (!WinApi.CryptAcquireContext(ref hProv, null, WinApi.MS_DEF_PROV,
                WinApi.PROV_RSA_FULL, WinApi.CRYPT_VERIFYCONTEXT))
                Failed("CryptAcquireContext");

           //128 bit hash object
            if (!WinApi.CryptCreateHash(hProv,
                WinApi.CALG_MD5, IntPtr.Zero, 0, ref hHash))
                Failed("CryptCreateHash");

     // add passphrase to hash  
            byte[] keyData = ASCIIEncoding.ASCII.GetBytes(passphrase);
            if (!WinApi.CryptHashData(hHash, keyData, (uint)keyData.Length, 0))
                Failed("CryptHashData");

            // create 40 bit crypto key from passphrase hash
            if (!WinApi.CryptDeriveKey(hProv, WinApi.CALG_RC2,
                hHash, WinApi.CRYPT_EXPORTABLE, ref hKey))
                Failed("CryptDeriveKey");

            // determine how large of a buffer is required
            // to hold the encrypted data
            uint dataLength = (uint)data.Length;
            uint bufLength = (uint)data.Length;
            if (!WinApi.CryptEncrypt(hKey, IntPtr.Zero, true,
                0, null, ref dataLength, bufLength))
                Failed("CryptEncrypt");

            // allocate and fill buffer with encrypted data
            buffer = new byte[dataLength];
            Buffer.BlockCopy(data, 0, buffer, 0, data.Length);

            dataLength = (uint)data.Length;
            bufLength = (uint)buffer.Length;
            if (!WinApi.CryptEncrypt(hKey, IntPtr.Zero, true,
                0, buffer, ref dataLength, bufLength))
                Failed("CryptEncrypt");
        }
      .......
     }

我試圖用Java實現它。 AFAIK,android中沒有默認的RC2加密提供程序,因此我使用了Spongy Castle庫(適用於android的Bouncycastle fork)。

這是我的Java代碼:

public static byte[] encryptLB(byte[] key, byte[] iv, byte[] unencrypted)
               throws NoSuchAlgorithmException, ... {
            MessageDigest digest = MessageDigest.getInstance("MD5");
            digest.update(key);
            byte[] hash = digest.digest(); //build the hash (128 bit)

              Cipher cipher = Cipher.getInstance("RC2/CBC/PKCS5Padding");
              cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(hash, "RC2"));
              byte[] unByte = unencrypted;
              byte[] encrypted = cipher.doFinal(unencrypted);
              return encrypted;
             }

這些功能的結果是不同的。 我做錯了什么?

我該怎么辦? 歡迎任何示例和建議。

最誠摯的問候。

UPD的主要目標是從兩個函數中獲取相同的字節數組。 我無法修改C#代碼。 首先,我想用C#代碼澄清我的意思:

  • 它從passphrase的字節數組創建MD5哈希
  • 它使用專有的WinApi.CryptDeriveKey函數生成加密密鑰
  • 該密鑰用於使用RC2算法加密數據

其次,我想知道是否存在WinApi.CryptDeriveKey函數的類似物-如我所見,這是主要問題。

抱歉,我的問題太籠統了,因為我不確定上面的問題( CryptDeriveKey )是唯一的。

不幸的是,我現在沒有Windows計算機可以對此進行測試,但是我認為這應該是可以互操作的。

public static byte[] encrypt(String passphrase, byte[] data) throws Exception {

    // Hash the ASCII-encoded passphrase with md5

    byte[] keyData = passphrase.getBytes(Charset.forName("US-ASCII"));
    MessageDigest md = MessageDigest.getInstance("MD5");
    byte [] md5HashOfKey = md.digest(keyData);

    // Need to use bouncycastle (spongycastle on Android) to get RC2

    Security.addProvider(new BouncyCastleProvider());

    Cipher rc2 = Cipher.getInstance("RC2/CBC/PKCS5PADDING");

    // Create an RC2 40-bit key from the 1st 5 bytes of the hash.

    SecretKeySpec rc2KeySpec = new SecretKeySpec(md5HashOfKey, 0, 5, "RC2");
    rc2.init(Cipher.ENCRYPT_MODE, rc2KeySpec);

    byte [] cipher = rc2.doFinal(data);

    return cipher;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM