【发布时间】:2013-11-18 08:22:45
【问题描述】:
我在 Java 中有以下代码使用 bouncy castle 提供程序进行密钥解包:
private static byte[] unwrapKey(byte[] toUnwrap, String key) throws Exception {
byte[] decoded = Base64.decode(toUnwrap);
if (decoded == null || decoded.length <= 16) {
throw new RuntimeException("Bad input data.");
}
byte[] salt = new byte[16];
byte[] wrappedKey = new byte[decoded.length - 16];
System.arraycopy(decoded, 0, salt, 0, 16);
System.arraycopy(decoded, 16, wrappedKey, 0, decoded.length - 16);
PBEKeySpec pbeKeySpec = new PBEKeySpec(key.toCharArray());
SecretKey wrapperKey = SecretKeyFactory.getInstance("PBEWITHSHA256AND256BITAES-CBC-BC").generateSecret(pbeKeySpec);
PBEParameterSpec parameterSpec = new PBEParameterSpec(salt, 10);
Cipher decCipher = Cipher.getInstance("AES/GCM/NoPadding", bcProvider);
decCipher.init(Cipher.UNWRAP_MODE, wrapperKey, parameterSpec);
return decCipher.unwrap(wrappedKey, "AES", Cipher.SECRET_KEY).getEncoded();
}
现在,我需要在C# 中做同样的事情。问题是即使有一个 BC 到 C# 的端口,我仍然无法让它工作。尝试了不同的东西,总是得到一些例外。
例如,此代码在倒数第二行抛出“pad block损坏”异常:
byte[] decoded = Convert.FromBase64String(toUnwrap);
if (decoded == null || decoded.Length <= 16) {
throw new System.ArgumentException("Bad input data", "toUnwrap");
}
byte[] salt = new byte[16];
byte[] wrappedKey = new byte[decoded.Length - 16];
Array.Copy(decoded, 0, salt, 0, 16);
Array.Copy(decoded, 16, wrappedKey, 0, decoded.Length - 16);
int iterationCount = 10;
String alg = "PBEWithSHA256And256BitAES-CBC-BC";
Asn1Encodable defParams = PbeUtilities.GenerateAlgorithmParameters(alg, salt, iterationCount);
char[] password = key.ToCharArray();
IWrapper wrapper = WrapperUtilities.GetWrapper(alg);
ICipherParameters parameters = PbeUtilities.GenerateCipherParameters(alg, password, defParams);
wrapper.Init(false, parameters);
byte[] pText = wrapper.Unwrap(wrappedKey, 0, wrappedKey.Length);
return pText.ToString();
我怀疑 C# 默认使用不同类型的填充,但不知道如何像在 Java 代码中那样强制“NoPadding”。
我不确定,如果 JAVA 代码使用 rfc3994 是不是这种情况,因为在 RFC 中您需要提供 IV,而这里有盐,但没有 IV。
我想知道以前是否有人这样做过,如果有,c# 的类比是什么。
【问题讨论】:
-
您会遇到哪些例外情况?
-
在问题中添加了代码。
标签: c# java cryptography aes bouncycastle