繁体   English   中英

将 Java AES/GCM/NoPadding 算法转换为 C#

[英]Convert Java AES/GCM/NoPadding algorithm to C#

我正在尝试转换此 java 代码:

package ffsd;

import java.security.MessageDigest;
import java.util.Arrays;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class GatewayEncryptUtil {
  public static String encrypt(String plainText, String key) throws Exception {
    return new String(Base64.getEncoder().encode(doCrypt(plainText.getBytes(), 1, key)));
  }
  
  public static byte[] doCrypt(byte[] inputText, int operation, String key) throws Exception {
    MessageDigest mDigest = MessageDigest.getInstance("SHA-512");
    byte[] secretKey = key.getBytes();
    byte[] digestSeed = mDigest.digest(secretKey);
    byte[] hashKey = Arrays.copyOf(digestSeed, 16);
    
    Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
    SecretKeySpec skspec = new SecretKeySpec(hashKey, "AES");
    String cipherKey = new String(secretKey);
    GCMParameterSpec gcmParams = new GCMParameterSpec(128, cipherKey.substring(0, 16).getBytes());
    cipher.init(operation, skspec, gcmParams);
    return cipher.doFinal(inputText);
  }
  
  public static void main(String[] args) {
    try {
      System.out.println(encrypt("Password", "1234567890123456"));
    } catch (Exception e) {
      e.printStackTrace();
    } 
  }
}

到 C# .NET 5.0 使用新的 AesGcm 类:

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

namespace ConsoleApp3
{
    class Program
    {
        static void Main(string[] args)
        {
            string inputText = "Password";
            string msgId = "1234567890123456";

            byte[] hashKey;
            byte[] secretKey = Encoding.ASCII.GetBytes(msgId);

            using (var hasher = SHA512.Create())
            {
                byte[] digestSeed = hasher.ComputeHash(secretKey);
                hashKey = new byte[16];
                Array.Copy(digestSeed, hashKey, hashKey.Length);
            }

            using (var aesGcm = new AesGcm(hashKey))
            {
                byte[] nonce = new byte[AesGcm.NonceByteSizes.MaxSize];
                byte[] plainText = Encoding.ASCII.GetBytes(inputText);
                byte[] authTag = new byte[AesGcm.TagByteSizes.MaxSize];
                byte[] cipherText = new byte[plainText.Length];

                aesGcm.Encrypt(nonce, plainText, cipherText, authTag);
                string cipherTextBase64 = Convert.ToBase64String(cipherText);
                string authTagBase64 = Convert.ToBase64String(authTag);

                Console.WriteLine(cipherTextBase64);
                Console.WriteLine(authTagBase64);
            }
        }
    }
}

但我不知道 nonce 应该是什么。 在任何地方的 java 代码中都没有看到。 任何人都可以给我任何指示吗? java代码的结果是:“gc1zTHlIPQusN5e+Rjq+veDoIYdU1nCQ”我的显然不完整,没有接近。

IV 和 Nonce 是同一个意思。

IV 是 GCMParameterSpec 的第二个参数:

GCMParameterSpec gcmParams = new GCMParameterSpec(128, cipherKey.substring(0, 16).getBytes());

.NET 称之为 Nonce。

我能够使用 BouncyCastle 将其转换为 C#:

using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using System;
using System.Security.Cryptography;
using System.Text;

namespace ConsoleApp3
{
    class Program
    {
        static void Main(string[] args)
        {
            string inputText = "Password";
            string msgId = "1234567890123456";

            string value = Encrypt(inputText, msgId);
            Console.WriteLine(value);
        }

        public static string Encrypt(string plainText, string msgId)
        {
            const byte GcmTagSize = 16;

            byte[] hashKey;
            byte[] secretKey = Encoding.ASCII.GetBytes(msgId);

            using (var hasher = SHA512.Create())
            {
                byte[] digestSeed = hasher.ComputeHash(secretKey);
                hashKey = new byte[16];
                Array.Copy(digestSeed, hashKey, hashKey.Length);
            }

            var keyParameter = new KeyParameter(hashKey);
            var keyParameters = new AeadParameters(keyParameter, GcmTagSize * 8, secretKey);

            var cipher = CipherUtilities.GetCipher("AES/GCM/NoPadding");
            cipher.Init(true, keyParameters);

            var plainTextData = Encoding.ASCII.GetBytes(plainText);
            var cipherText = cipher.DoFinal(plainTextData);

            return Convert.ToBase64String(cipherText);
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM