[英]Convert encrypt/decrypt from Java to C# using bouncycastle
I'm trying to convert a couple of function from Java to c# using Portable.BouncyCastle and while there are plenty of example out there, I don't seem to be able to find one to match my requirements as most example seem to explain one specific encryption/decryption method while this function appears to be more generic.我正在尝试使用 Portable.BouncyCastle 将几个函数从 Java 转换为 c#,虽然那里有很多示例,但我似乎无法找到一个符合我的要求的函数,因为大多数示例似乎都在解释一个特定的加密/解密方法,而此功能似乎更通用。 I could be wrong of course as I'm a complete newbie to this and don't have any experience in either BouncyCastle, Java or encryption, so please bear with me on this one.
我当然可能是错的,因为我是一个完全的新手,并且在 BouncyCastle、Java 或加密方面没有任何经验,所以请耐心等待。
The java function is: 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);
}
I found some code from BouncyCasle where I can match most of the functionality from what I can see:我从 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: 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. spec parameter: 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: You can see that when cypher is called from java, it passes the AlgorithmParameterSpec spec
as new IvParameterSpec(iv)
but with BouncyCastle, it seems to be expecting a key? 3. IvParameterSpec:你可以看到,当从java调用cypher时,它将
AlgorithmParameterSpec spec
作为new IvParameterSpec(iv)
传递,但是对于BouncyCastle,它似乎在期待一个密钥?
ParametersWithIV(key, N)
Will that difference have any impact on the encryption/decryption?这种差异对加密/解密有什么影响吗?
This is current my attempt at "converting" this function:这是我当前尝试“转换”此功能的方法:
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);
}
As you can see I've changed the spec parameter to ICipherParameters spec
but I don't know if this will work as when using Bouncy, it looks like that when I create a new ParametersWithIV
, it needs a key and from the test sample I provided above, that key is created using KeyParameter key = ParameterUtilities.CreateKeyParameter("AES", K);
如您所见,我已将 spec 参数更改为
ICipherParameters spec
但我不知道这是否会像使用 Bouncy 时一样工作,看起来当我创建一个new ParametersWithIV
,它需要一个密钥,并且来自测试样本我上面提供的密钥是使用KeyParameter key = ParameterUtilities.CreateKeyParameter("AES", K);
so technically won't work when trying to call my Cipher function as I will have called this function yet.所以在尝试调用我的 Cipher 函数时从技术上讲是行不通的,因为我已经调用了这个函数。 Should I change spec parameter to iv and pass a
byte[]
instead?我应该将 spec 参数更改为 iv 并传递一个
byte[]
吗?
Apologies if there is confusion or if things are not explained correctly but as I said, I'm new to this and trying to understand it better while also converting.如果出现混淆或未正确解释,我深表歉意,但正如我所说,我是新手,并试图在转换的同时更好地理解它。 I hope most of it makes sense and you'll be able to help.
我希望其中的大部分内容都有意义,并且您将能够提供帮助。
Many Thanks.非常感谢。
PS: Note that I'm not in a position to test these in Java yet, but I will hopefully have an environment set up correctly in the new few days which will hopefully help testing values between .net & java. PS:请注意,我还不能在 Java 中测试这些,但我希望在新的几天内可以正确设置环境,这将有助于测试 .net 和 java 之间的值。
UPDATE 1更新 1
Passing AES/CCM/NoPadding
to:将
AES/CCM/NoPadding
传递给:
KeyParameter key = ParameterUtilities.CreateKeyParameter
Throws an error, so this partially answers one of my questions.抛出一个错误,所以这部分回答了我的一个问题。 Is there a function in
BouncyCastle
to determine the correct value that is required ie AES
when AES/CCM/NoPadding
is passed?当
AES/CCM/NoPadding
被传递时, BouncyCastle
是否有一个函数来确定所需的正确值,即AES
?
Ended up using the code below as it appears to be working as expected but still annoyed I had to hardcode the AES
as the key of IV parameter part.最终使用下面的代码,因为它似乎按预期工作,但仍然很恼火我不得不将
AES
硬编码为 IV 参数部分的键。 Ideally I would have liked this to have been based on my Algorithm.理想情况下,我希望这是基于我的算法。 So, now I have a single function to encrypt and decrypt:
所以,现在我有一个函数来加密和解密:
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);
}
Hope this helps.希望这可以帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.