错误的算法:c#需要AES或Rijndael

时间:2017-09-17 07:23:53

标签: c# algorithm encryption aes encryption-symmetric

我有andriod代码,我试图将其转换为c#。它是一个简单的加密类。但当我尝试用它解密数据时,我抓住了:Wrong algorithm: AES or Rijndael required 这是我转换的代码:

public static string decrypt(string data)
{
    byte[] dataBytes = Convert.FromBase64String(data);
    SecretKey secretKey = getSecretKey(hashTheKey("ABCD"));

    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

    cipher.init(2, secretKey, new IvParameterSpec(new byte[16]),
            SecureRandom.getInstance("SHA1PRNG"));
    var x = cipher.doFinal(dataBytes);
    return System.Text.Encoding.UTF8.GetString(x);
}
public static SecretKey getSecretKey(char[] key)
{
    var secretKeyType = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
    var secretkey = secretKeyType.generateSecret(new PBEKeySpec(key,
            System.Text.Encoding.UTF8
                .GetBytes("ABCD"),
            100, 128)).getEncoded();

    return new SecretKeySpec(secretkey, "AES/CBC/PKCS5Padding");
}
public static char[] hashTheKey(string key)
{
    MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
    messageDigest.update(System.Text.Encoding.UTF8.GetBytes(key));
    return Convert.ToBase64String(messageDigest.digest()).ToCharArray();
}

这是我原来的安卓代码:

private char[] hashTheKey(String key) throws UnsupportedEncodingException, NoSuchAlgorithmException {
    MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
    messageDigest.update(key.getBytes());
    return Base64.encodeToString(messageDigest.digest(),
                                 Base64.NO_PADDING).toCharArray();
}

private SecretKey getSecretKey(char[] key) throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeySpecException {
    return new SecretKeySpec(
        SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1")
        .generateSecret(new PBEKeySpec(key,
                       "ABCD".getBytes("UTF8"),
                       100, 128)).getEncoded(), "AES");
}

public String decrypt(String data) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException, InvalidKeySpecException {
    byte[] dataBytes = Base64.decode(data, Base64.DEFAULT);
    SecretKey secretKey = getSecretKey(hashTheKey("ABCD"));
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(2, secretKey, new IvParameterSpec(new byte[16]),
            SecureRandom.getInstance("SHA1PRNG"));
    return new String(cipher.doFinal(dataBytes));
}

2 个答案:

答案 0 :(得分:2)

正在使用相同的完善的加密算法,但在如何调用它们的方法上有所不同。仍然可以转换代码。

一个关键点是base64编码的差异--C#总是使用填充。

转换后的代码如下:

const int KeySize = 128;

static string HashTheKey(string key) {
  String hashKey;
  using (var sha = new SHA1Managed()) {
   hashKey = Convert.ToBase64String(sha.ComputeHash(Encoding.UTF8.GetBytes(key)));
  }
  // beware - you're on C# now so remove the padding and add the newline to match java
  return hashKey.Replace("=", "") + "\n";
}

static byte[] GetSecretKey(string password) {
  var salt = Encoding.UTF8.GetBytes("JVAaVhAiddKAaghraikhmaini");
  using (var pass = new Rfc2898DeriveBytes(password, salt, 65536)) {
    return pass.GetBytes(KeySize / 8);
  }
}

static void Main(string[] args) {
  string encrypted = "vtlkQHTz7/oz2weuAAkLz2Q5c2yj2LGukF7SHJjT+TA8oRLixTQSXQ7dG1O736hyT1HJxcz0P4DzzVaO5chWKKSJQ2uPEpDQJu/fZGguqDw=";
  byte[] encryptedBytes = Convert.FromBase64String(encrypted);
  using (var aes = new AesManaged()) {
    aes.KeySize = KeySize;
    aes.Padding = PaddingMode.PKCS7;
    aes.Key = GetSecretKey(HashTheKey("Android"));
    // you're using the same init vector in your android code
    aes.IV = new byte[16];
    using (var decryptor = aes.CreateDecryptor()) {
      // dumps {"barcode":"12345678","token":"cad603fc-1e53-4a95-9150-f1694baa07f9"}
      Console.Out.WriteLine(Encoding.UTF8.GetString(decryptor.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length)));
    }
  }
}

答案 1 :(得分:-2)

C#不处理加密算法,因为Android或java你必须使用AES或Rijndael算法,因为你可以看到错误转换为加密Base64的简单文本,反之亦然你可以在C#中使用以下类

watchOS