2016-05-03 114 views
2

我正試圖使用​​Portable.BouncyCastle將幾個函數從Java轉換爲c#,雖然有很多示例,但我似乎無法找到一個匹配我的要求,因爲大多數例子似乎解釋了一種特定的加密/解密方法,而這個功能似乎更通用。我當然可能是錯的,因爲我是一個完全新手,在BouncyCastle,Java或加密方面都沒有任何經驗,所以請在這一個上跟我一起。使用bouncycastle將加密/解密從Java轉換爲C#

Java函數是:

public static byte[] Cipher(int mode, byte[] key, 
     byte[] data, string algorithm, AlgorithmParameterSpec spec) 
{ 
    Cipher cipher = Cipher.getInstance(algorithm); 
    SecretKeySpec keySpec = new SecretKeySpec(key, algorithm); 

    if (spec != null) 
    cipher.init(mode, keySpec, spec); 
    else 
    cipher.init(mode, keySpec); 

    return cipher.doFinal(data); 
} 

我發現從BouncyCasle一些代碼,在那裏我可以匹配的大部分功能,從我所看到的:

byte[] K = Hex.Decode("404142434445464748494a4b4c4d4e4f"); 
byte[] N = Hex.Decode("10111213141516"); 
byte[] P = Hex.Decode("68656c6c6f20776f726c642121"); 
byte[] C = Hex.Decode("39264f148b54c456035de0a531c8344f46db12b388"); 

KeyParameter key = ParameterUtilities.CreateKeyParameter("AES", K); 

IBufferedCipher inCipher = CipherUtilities. 
    GetCipher("AES/CCM/NoPadding"); 

inCipher.Init(true, new ParametersWithIV(key, N)); 

byte[] enc = inCipher.DoFinal(P); 

1 SecretKeySpec:

SecretKeySpec keySpec = new SecretKeySpec(key, algorithm); 

How do I create this using BC? Is that the equivalent of the SecretKeySpec: 

    KeyParameter key = ParameterUtilities.CreateKeyParameter("AES", K); 

If it is, can I pass the "AES/CCM/NoPadding" instead of AES as it is done in Java? 

2 。規格參數:

It passes parameters of type IvParameterSpec to the Cypher function when called from `Java` via the `AlgorithmParameterSpec spec` parameter: 

Cipher(ENCRYPT_MODE, key, clearBytes, 
       algorithm, 
       new IvParameterSpec(iv)) 

`BouncyCastle` does not have an overloaded function for `.Init` to allow me to pass the spec parameter as it does in `Java`, so how do I mimic this behaviour? 

3 IvParameterSpec:你可以看到,當暗號是從Java調用,它通過AlgorithmParameterSpec specnew IvParameterSpec(iv)但BouncyCastle的,似乎在期待的關鍵?

ParametersWithIV(key, N) 

這種差異會對加密/解密產生什麼影響嗎?

這是當前我試圖在「轉換」這個功能:

public static byte[] Cipher(bool isEncrypt, byte[] key, byte[] data, 
          string algorithm, ICipherParameters spec) 
    { 
     IBufferedCipher cipher = CipherUtilities.GetCipher(algorithm); 
     KeyParameter keySpec = ParameterUtilities. 
      CreateKeyParameter(algorithm, key); 

     cipher.Init(isEncrypt, new ParametersWithIV(keySpec, 
      keySpec.GetKey())); 

     return cipher.DoFinal(data); 
    } 

正如你可以看到我已經改變了規格參數ICipherParameters spec,但我不知道這是否會使用快活時,作爲工作,它看起來像是當我創建一個new ParametersWithIV時,它需要一個密鑰,並且從上面提供的測試示例中,使用KeyParameter key = ParameterUtilities.CreateKeyParameter("AES", K);創建該密鑰,因此在嘗試調用我的密碼函數時技術上不起作用,因爲我將該函數稱爲此函數然而。我是否應該將規格參數更改爲iv並改爲通過byte[]

道歉,如果有混淆或如果事情沒有正確解釋,但正如我所說,我是新來的,並試圖理解它,同時也轉換。我希望它的大部分都是有道理的,你將能夠提供幫助。

很多謝謝。

PS:請注意,我還沒有能力在Java中測試它們,但我希望在新的幾天內能夠正確設置一個環境,這將有助於測試.net & java之間的值。

更新1

傳遞到:

KeyParameter key = ParameterUtilities.CreateKeyParameter 

拋出一個錯誤,所以這部分回答了我的問題之一。在BouncyCastle中是否有函數來確定所需的正確值,即當通過時AES

回答

1

結束了使用下面的代碼,因爲它看起來像預期的工作,但仍然惱火我必須硬編碼AES作爲IV參數部分的關鍵。理想情況下,我希望這是基於我的算法。所以,現在我有一個函數來加密和解密:

public static byte[] Cipher(bool forEncryption, byte[] key, 
byte[] data, string algorithm, byte[] iv) 
{ 
    IBufferedCipher cipher = CipherUtilities.GetCipher(algorithm); 
    KeyParameter keySpec = ParameterUtilities.CreateKeyParameter("AES", key); 
    cipher.Init(forEncryption, new ParametersWithIV(keySpec, iv)); 
    return cipher.DoFinal(data); 
} 

希望這會有所幫助。