gpt4 book ai didi

java - AES Rijndael 解密 C#

转载 作者:行者123 更新时间:2023-11-30 05:26:45 24 4
gpt4 key购买 nike

我必须解密一些使用 AES256 Rijndael 加密发送的数据。我有我的伙伴使用的加解密机制,是用JAVA开发的,我不太熟悉,但无法在C#中转置它。

给我的 key 长度为 10 个字符。

我认为下面的代码是可以的,除了 IV 计算。您将首先找到 Java 代码,然后找到 C# :

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class UtilsCrypto {

/* Rijndael/CFB8/NoPadding is default cipher */
final static String CHIPHER = "Rijndael/CFB8/NoPadding";

public static final String MESSAGE_DIGEST_ALGORITHM = "MD5";
public static final String AES = "AES";
public static final String AES_ECB_NO_PADDING = "AES/ECB/NoPadding";

private static byte[] md5(final String input) throws NoSuchAlgorithmException {
final MessageDigest md = MessageDigest.getInstance(MESSAGE_DIGEST_ALGORITHM);
return md.digest(input.getBytes());
}

private Cipher initCipher(final int mode, final String secretKey) throws Exception {
final byte[] key = md5(secretKey);
final byte[] iv = md5(secretKey);

final SecretKeySpec skeySpec = new SecretKeySpec(key, AES);

/* This valid with other ciphers than Rijndael/CFB8/NoPadding */
// final IvParameterSpec initialVector = new IvParameterSpec(iv);

/* Use this with Rijndael/CFB8/NoPadding */
final IvParameterSpec initialVector = new IvParameterSpec(getIvBytes(iv));

final Cipher cipher = Cipher.getInstance(CHIPHER);
cipher.init(mode, skeySpec, initialVector);

return cipher;
}

public String encrypt(final String dataToEncrypt, final String secretKey) {
if (Utils.isEmpty(secretKey))
return dataToEncrypt;

String encryptedData = null;
try {
final Cipher cipher = initCipher(Cipher.ENCRYPT_MODE, secretKey);
final byte[] encryptedByteArray = cipher.doFinal(dataToEncrypt.getBytes(Charset.forName("UTF8")));
final BASE64Encoder enc = new BASE64Encoder();
encryptedData = enc.encode(encryptedByteArray);
encryptedData = encryptedData.replace("+", "-");
encryptedData = encryptedData.replace("/", "_");
} catch (Exception e) {
System.err.println("Problem encrypting the data");
e.printStackTrace();
}

return encryptedData;
}

public String decrypt(final String encryptedData, final String secretKey) {
String decryptedData = null;
String inData = encryptedData;
try {
final Cipher cipher = initCipher(Cipher.DECRYPT_MODE, secretKey);
final BASE64Decoder dec = new BASE64Decoder();
inData = inData.replace("-", "+");
inData = inData.replace("_", "/");
final byte[] encryptedByteArray = dec.decodeBuffer(inData); // ok
final byte[] decryptedByteArray = cipher.doFinal(encryptedByteArray);
decryptedData = new String(decryptedByteArray, "UTF8");
} catch (Exception e) {
System.err.println("Problem decrypting the data");
e.printStackTrace();
}
return decryptedData;
}

/**
* This method is only for Rijndael/CFB8/NoPadding
*
* @param hashedKey
* md5
* @return byte array
* @throws Exception
* If any exceptions.
*/
// on passe en arg le hash de la clé
protected byte[] getIvBytes(byte[] hashedKey) throws Exception {
byte[] inputBytes = new byte[16]; // init son tableau a 16 bytes
final SecretKey key = new SecretKeySpec(hashedKey, AES); // secretKey
final Cipher cipher = Cipher.getInstance(AES_ECB_NO_PADDING);
cipher.init(Cipher.ENCRYPT_MODE, key); // chiffre sa clé en AES avec un IV
return cipher.doFinal(inputBytes);
}
}

现在这是我到目前为止所尝试的:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Xml;
using System.Net;
using System.Web;
using System.Web.Services;
using Newtonsoft.Json;
using System.Security.Cryptography;
using System.Text;

namespace test
{
public byte[] getIVBytes(byte[] hashedKey)
{
byte[] inputBytes = new byte[16];
AesManaged tdes = new AesManaged();
tdes.Key = hashedKey;
tdes.Mode = CipherMode.ECB;
tdes.BlockSize = 128;
tdes.Padding = PaddingMode.None;
ICryptoTransform crypt = tdes.CreateEncryptor();
byte[] bla = crypt.TransformFinalBlock(hashedKey, 0, inputBytes.Length);
return bla;
}

[WebMethod]
public string decrypt(String input, String key)
{
byte[] md5KeyHash;
using (MD5 md5 = MD5.Create())
{
md5KeyHash = md5.ComputeHash(Encoding.UTF8.GetBytes(key));
}
input = input.Replace("-", "+");
input = input.Replace("_", "/");
input = input.Replace(" ", "");
byte[] data = Convert.FromBase64String(input); // récupérer l'array de bytes du message chiffré encodé en b64
String decrypted;
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Mode = CipherMode.CFB;
rijAlg.BlockSize = 128;
rijAlg.Padding = PaddingMode.None;
rijAlg.Key = md5KeyHash;
rijAlg.IV = getIVBytes(md5KeyHash);

ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, null);
using (MemoryStream msDecrypt = new MemoryStream(data))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
decrypted = srDecrypt.ReadToEnd();
}
}
}
}
return decrypted;
}

代码似乎是“正确的”,因为除了以下错误之外没有抛出任何错误:XML 错误分析:在文本内容中发现无效字符。在:http://localhost:55175/WebService1.asmx/decrypt第 2 行,col44 :�Me��� >m�H�Z�af2ɾ`A�ٖ�H$�&/

我错过了什么?

最佳答案

C# 代码中存在一些错误:

  • getIVBytes 方法中,替换行

    byte[] bla = crypt.TransformFinalBlock(hashedKey, 0, inputBytes.Length);

    byte[] bla = crypt.TransformFinalBlock(inputBytes, 0, inputBytes.Length); // encrypt inputBytes
  • decrypt方法中,在CreateDecryptor调用之前添加

    rijAlg.FeedbackSize = 8; // Use CFB8

    并替换行

    ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, null);

    ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV); // Consider the IV

然后可以使用 C# 代码将发布的密文解密为发布的明文。

关于java - AES Rijndael 解密 C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58415430/

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