gpt4 book ai didi

java - 在 Java 中解密 Rijndael,使用 .NET 加密

转载 作者:太空宇宙 更新时间:2023-11-04 06:59:56 25 4
gpt4 key购买 nike

我们有一个用例,我们希望解密之前使用 .NET 加密的 java 数据

这是用于在 .NET 中加密和解密数据的 Crypt 类:

https://gist.github.com/epinapala/9400064

我分离了 Decrypt 方法并执行,它在 .NET 中运行良好,我希望移植以下代码:

using System.IO;
using System;
using System.Text;
using System.Security.Cryptography;

class Program
{
static void Main()
{
{
string line = "f5EBWYipPKG1FpyTEP7pyPLLJNpqrvwYJFs8iMw9mOY$";

line = line.Replace('-', '+').Replace('_', '/').Replace('$', '=');

while (line.Length % 4 != 0){
line = line.PadRight(line.Length + (4 - line.Length % 4), '=');
}
Console.WriteLine(line);


byte[] inputBuffer = Convert.FromBase64String(line);
Console.WriteLine(inputBuffer.Length);
byte[] numArray = new byte[16];
byte[] key = new PasswordDeriveBytes("ThisIsMyKey", new byte[13]
{
(byte) 73,
(byte) 118,
(byte) 97,
(byte) 110,
(byte) 32,
(byte) 77,
(byte) 101,
(byte) 100,
(byte) 118,
(byte) 101,
(byte) 100,
(byte) 101,
(byte) 118
}).GetBytes(16);

Rijndael rijndael = GetRijndael(key);

for (int index = 0; index < 16; ++index){
numArray[index] = inputBuffer[index];
}
rijndael.IV = numArray;

string decodedString = Encoding.UTF8.GetString(rijndael.CreateDecryptor().TransformFinalBlock(inputBuffer, 16, inputBuffer.Length - 16));
Console.WriteLine(decodedString);
}
}


private static Rijndael GetRijndael(byte[] key)
{
Rijndael rijndael = Rijndael.Create();
rijndael.Mode = CipherMode.CBC;
rijndael.KeySize = key.Length * 8;
rijndael.Key = key;
rijndael.Padding = PaddingMode.PKCS7;
return rijndael;
}
}

这是我迄今为止尝试过的:

   public static void main() {
ecnryptedData = "f5EBWYipPKG1FpyTEP7pyPLLJNpqrvwYJFs8iMw9mOY$";
ecnryptedData = ecnryptedData.replace('-', '+')
.replace('_', '/').replace('$', '=');

while (ecnryptedData.length() % 4 != 0) {
ecnryptedData = StringUtils.rightPad(ecnryptedData, ecnryptedData.length() + (4 - ecnryptedData.length() % 4),
"=");
}
System.out.println(Decrypt(ecnryptedData, "ThisIsMyKey"));
}

public static String Decrypt(String text, String key) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] keyBytes = new byte[16];
byte[] b = key.getBytes("UTF-8");
int len = b.length;
if (len > keyBytes.length) len = keyBytes.length;
System.arraycopy(b, 0, keyBytes, 0, len);
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
AlgorithmParameterSpec spec = new IvParameterSpec(keyBytes);
cipher.init(Cipher.DECRYPT_MODE, keySpec, spec);

BASE64Decoder decoder = new BASE64Decoder();
byte[] results = cipher.doFinal(decoder.decodeBuffer(text));
return new String(results, "UTF-8");
}

我收到异常:“鉴于最终 block 未正确填充”。不知道我做错了什么。感谢您对这个问题的任何帮助。

[[编辑]]:

我明白了。我错过的是我使用了错误的盐。我将 .NET 代码中使用的常量盐(作为字节)解码为其字符串计数器部分,并将其用作我的 Java 代码中的盐。

也感谢在这里找到的PasswordDerivedBytes类:

https://github.com/getkksingh/TimesSSO/blob/fc78e4b30d5fd347341757c02eea6c9271575515/src/java/com/timesgroup/sso/hibernate/apis/PasswordDeriveBytes.java

private static byte[] decryptData(byte[] data, String password,
String paddingMode, String salt) throws Exception {
if (data == null || data.length == 0)
throw new IllegalArgumentException("data is empty");
if (password == null || password == "")
throw new IllegalArgumentException("password is empty");
if (salt == null || salt == "")
salt = ".";
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
byte[] saltBytes = salt.getBytes("UTF8");
byte[] passBytes = password.getBytes("UTF8");

PKCS5S1ParametersGenerator generator = new PasswordDeriveBytes(
new SHA1Digest());
generator.init(passBytes, saltBytes, 100);

byte[] key = ((KeyParameter) generator.generateDerivedParameters(256))
.getKey();
passBytes = new byte[16];
saltBytes = new byte[16];
System.arraycopy(key, 0, passBytes, 0, 16);
System.arraycopy(key, 16, saltBytes, 0, 16);

Cipher cipher = Cipher.getInstance("AES/CBC/" + paddingMode, "BC");
SecretKeySpec keySpec = new SecretKeySpec(passBytes, "AES");
cipher.init(Cipher.DECRYPT_MODE, keySpec,
new IvParameterSpec(saltBytes));

byte[] original = cipher.doFinal(data);
return original;
}

最佳答案

您在 C# 代码中使用自定义 Base64 变体:_- 作为字符 62 和 63,$ 作为填充。 C# 代码在尝试解码之前将它们转换为正常的 Base64。

您的 java 代码将无效数据传递给 Base64 解码器。在代码到达加密之前,这应该抛出一个 IllegalArgumentException

另一个问题是您的 C# 代码使用 PBKDF1 从密码中派生 key ,而 java 代码直接使用密码作为 key 字节。

关于java - 在 Java 中解密 Rijndael,使用 .NET 加密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22236199/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com