问题描述
我在 C# 和 Java 中使用了一些加密函数,它们的输出似乎不匹配。我已经为此挣扎了几天,我想我终于可以求助于这里了。
输入字符串:“a”
这是java实现的一个片段:
CryptoAesGcmService.getInstance().encryptData("a",aes_key)
import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
public class CryptoAesGcmService {
private static CryptoAesGcmService instance;
private static final int GCM_TAG_LENGTH = 16;
private static final int GCM_IV_LENGTH = 12;
public static CryptoAesGcmService getInstance() {
if (instance == null) {
instance = new CryptoAesGcmService();
}
return instance;
}
public String encryptData(String plaintext,String key) throws Exception {
return encrypt2(plaintext,key,createGCMParameter());
}
private static String encrypt(String plaintext,String key,GCMParameterSpec gcmParameterSpec) throws Exception {
// return plaintext;
try {
byte[] plainTextByte = plaintext.getBytes(StandardCharsets.UTF_8);
Cipher cipher = Cipher.getInstance("AES/GCM/nopadding");
cipher.init(Cipher.ENCRYPT_MODE,createSecretKeySpec(key),gcmParameterSpec);
byte[] cipherText = cipher.doFinal(plainTextByte);
return Base64.getEncoder().encodetoString(cipherText);
} catch (Exception e) {
throw new Exception("Unexpected exception occur.",e);
}
}
private static SecretKeySpec createSecretKeySpec(String secretKey) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(secretKey.getBytes(StandardCharsets.UTF_8));
return new SecretKeySpec(md.digest(),"AES");
}
private static GCMParameterSpec createGCMParameter() {
return new GCMParameterSpec(GCM_TAG_LENGTH * 8,new byte[GCM_IV_LENGTH]);
}
}
输出:修复 3UhjsGLxeoCyP/cd7c7p++I=
这是 .Net 实现的一个片段:
aes.Encrypt("a",aes_key);
using System;
using System.Buffers.Binary;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
namespace api.Class
{
public class AESGCM
{
private const int KEY_BIT_SIZE = 256;
private const int MAC_BIT_SIZE = 128;
private const int NONCE_BIT_SIZE = 128;
private readonly SecureRandom random;
private static AESGCM instance;
public static AESGCM Instance //property of this class. Create an instance if it is not created yet
{
get
{
if (instance == null)
instance = new AESGCM();
return instance;
}
}
public AESGCM()
{
random = new SecureRandom();
}
//encrypt with strings
public string Encrypt(string text,string key,byte[] nonSecretPayload = null)
{
if (string.IsNullOrEmpty(text))
throw new ArgumentException("Text required!","text");
//var decodedKey = Convert.FromBase64String(key);
var decodedKey = Encoding.UTF8.GetBytes(key);
var plainText = Encoding.UTF8.GetBytes(text);
var cipherText = EncryptWithKey(plainText,decodedKey,nonSecretPayload);
return Convert.ToBase64String(cipherText);
}
//encrypt with byte array
private byte[] EncryptWithKey(byte[] text,byte[] key,byte[] nonSecretPayload = null)
{
if (key == null || key.Length != KEY_BIT_SIZE / 8)
throw new ArgumentException(String.Format("Key needs to be {0} bit!",KEY_BIT_SIZE),"key");
nonSecretPayload = nonSecretPayload ?? new byte[] { };
var nonce = new byte[NONCE_BIT_SIZE / 8];
random.NextBytes(nonce,nonce.Length);
var cipher = new GcmBlockCipher(new AesEngine());
var parameters = new AeadParameters(new KeyParameter(key),MAC_BIT_SIZE,nonce,nonSecretPayload);
cipher.Init(true,parameters);
var cipherText = new byte[cipher.GetoutputSize(text.Length)];
var len = cipher.ProcessBytes(text,text.Length,cipherText,0);
cipher.DoFinal(cipherText,len);
using (var combinedStream = new MemoryStream())
{
using (var binaryWriter = new BinaryWriter(combinedStream))
{
binaryWriter.Write(nonSecretPayload);
binaryWriter.Write(nonce);
binaryWriter.Write(cipherText);
}
return combinedStream.ToArray();
}
}
}
}
输出:总是在变化
示例 1
4BnestJ12YZIQsaFhOcufy1rgXW2/H5kBmPyBSVdf2qP
示例 2
z4xNJgr6YLg+lsCA2jUn0HKorN8UXrVm0QtKl10w/Yba
示例 3
0IxfAp2vIOmj3fvsJ25VVINHpnaxtZ5KNl89Qk7MNFcn
我想要输出 .net 相同的 java。我对加密和 Java 的了解都不够,不知道下一步该去哪里。任何指导将不胜感激
更新
我尝试遵循建议,但没有奏效。
using System;
using System.Text;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Parameters;
namespace api.Class
{
public class AESGCM
{
private const int KEY_BIT_SIZE = 256;
private const int MAC_BIT_SIZE = 128;
//encrypt with strings
public string Encrypt(string text,string key)
{
if (string.IsNullOrEmpty(text))
throw new ArgumentException("Text required!","text");
var decodedKey = Encoding.UTF8.GetBytes(key);
var plainText = Encoding.UTF8.GetBytes(text);
var cipherText = EncryptWithKey(plainText,decodedKey);
return Convert.ToBase64String(cipherText);
}
//encrypt with byte array
private byte[] EncryptWithKey(byte[] text,byte[] key)
{
if (key == null || key.Length != KEY_BIT_SIZE / 8)
throw new ArgumentException(String.Format("Key needs to be {0} bit!","key");
var nonce = new byte[12];
var cipher = new GcmBlockCipher(new AesEngine());
var parameters = new AeadParameters(new KeyParameter(key),nonce);
cipher.Init(true,len);
return cipherText;
}
}
}
输出:修复 7szCRlNpTMM+93eTi332Gdw=
最终代码
using System;
using System.Security.Cryptography;
using System.Text;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Parameters;
namespace api.Class
{
public class AESGCM
{
private const int KEY_BIT_SIZE = 256;
private const int MAC_BIT_SIZE = 128;
//encrypt with strings
public string Encrypt(string text,"text");
var decodedKey = sha256_hash(key);
var plainText = Encoding.UTF8.GetBytes(text);
var cipherText = EncryptWithKey(plainText,len);
return cipherText;
}
private byte[] sha256_hash(string value)
{
Byte[] result;
using (var hash = SHA256.Create())
{
Encoding enc = Encoding.UTF8;
result = hash.ComputeHash(enc.GetBytes(value));
}
return result;
}
}
}
输出:与java相同
非常感谢@user9014097
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)