[英]Convert encrypt/decrypt from Java to C# using bouncycastle
我正在嘗試使用 Portable.BouncyCastle 將幾個函數從 Java 轉換為 c#,雖然那里有很多示例,但我似乎無法找到一個符合我的要求的函數,因為大多數示例似乎都在解釋一個特定的加密/解密方法,而此功能似乎更通用。 我當然可能是錯的,因為我是一個完全的新手,並且在 BouncyCastle、Java 或加密方面沒有任何經驗,所以請耐心等待。
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 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調用cypher時,它將AlgorithmParameterSpec spec
作為new 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);
}
如您所見,我已將 spec 參數更改為ICipherParameters spec
但我不知道這是否會像使用 Bouncy 時一樣工作,看起來當我創建一個new ParametersWithIV
,它需要一個密鑰,並且來自測試樣本我上面提供的密鑰是使用KeyParameter key = ParameterUtilities.CreateKeyParameter("AES", K);
所以在嘗試調用我的 Cipher 函數時從技術上講是行不通的,因為我已經調用了這個函數。 我應該將 spec 參數更改為 iv 並傳遞一個byte[]
嗎?
如果出現混淆或未正確解釋,我深表歉意,但正如我所說,我是新手,並試圖在轉換的同時更好地理解它。 我希望其中的大部分內容都有意義,並且您將能夠提供幫助。
非常感謝。
PS:請注意,我還不能在 Java 中測試這些,但我希望在新的幾天內可以正確設置環境,這將有助於測試 .net 和 java 之間的值。
更新 1
將AES/CCM/NoPadding
傳遞給:
KeyParameter key = ParameterUtilities.CreateKeyParameter
拋出一個錯誤,所以這部分回答了我的一個問題。 當AES/CCM/NoPadding
被傳遞時, BouncyCastle
是否有一個函數來確定所需的正確值,即AES
?
最終使用下面的代碼,因為它似乎按預期工作,但仍然很惱火我不得不將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);
}
希望這可以幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.