java - 跨平台ECDH加密和解密Java和c#
问题描述
我不是加密专家。我们需要在 c# 中加密数据并在 java 中解密。我们能够在 c# 和 java 中加密和解密相同密钥的数据。当我们尝试在 c# 中加密字符串并在 java 中解密相同的字符串时,我们得到
com.nimbusds.jose.JOSEException:AES/GCM/NoPadding 解密失败:标签不匹配!
有人可以帮忙吗?
下面是用于加密数据的代码 C# 代码。
在 C# 中解密字符串的代码
public class JWK
{
public string alg { get; set; }
public int? created_at { get; set; }
public string crv { get; set; }
public int? expired_at { get; set; }
public string kid { get; set; }
public string kty { get; set; }
public string use { get; set; }
public string x { get; set; }
public string y { get; set; }
public string d { get; set; }
}
public static string stringkey = @" {
""y"": ""AGum7Ok3MsKuMfrGtYUoeRq09oXwuO5yiMcxDjPbZglLKaZK-Z_kGt3ZcakVavLx46ieXw4agldm9qV6KmBCf6d7"",
""kty"": ""EC"",
""d"": ""AaDyXhcUwH90OvzbYJvocSl7uYlZNRZvgj8yesGjtqUWfxmN50NIFfnBpKohNc3wkYqviScjevczATzibw0Cnlgp"",
""kty"": ""EC"",
""crv"": ""P-521"",
""x"": ""AeyTJd9u-0k3ihg5T1OKqc7xlfn-a5WWTwp0yeQLz03lTHotMhiuKYQGez5KgeuODtOyZNmNdcKN6WjlFuMmVlTd""
}";
static void Main(string[] args)
{
string secretMessage = "Hello world";
string encryptedValue = Encrypt(secretMessage);
Console.WriteLine("Encrypted Value: "+encryptedValue);
string decryptedValue = Decrypt(encryptedValue);
Console.WriteLine("Decrypted Value: "+decryptedValue);
string encryptedValuewithByteCode = EncryptWithByteCode(secretMessage);
Console.WriteLine("Decrypted Value: " + Decrypt(encryptedValuewithByteCode));
}
public static string Encrypt(string encryptValue) {
JsonTextReader reader = new JsonTextReader(new StringReader(stringkey));
var jwk = JsonSerializer.CreateDefault().Deserialize<JWK>(reader);
var publicECCKey = EccKey.New(WebEncoders.Base64UrlDecode(jwk.x), WebEncoders.Base64UrlDecode(jwk.y), usage: CngKeyUsages.KeyAgreement);
string token = Jose.JWT.Encode(encryptValue, publicECCKey, JweAlgorithm.ECDH_ES, JweEncryption.A256GCM);
return token;
}
public static string EncryptWithByteCode(string encryptValue)
{
JsonTextReader reader = new JsonTextReader(new StringReader(stringkey));
var jwk = JsonSerializer.CreateDefault().Deserialize<JWK>(reader);
var publicECCKey = EccKey.New(WebEncoders.Base64UrlDecode(jwk.x), WebEncoders.Base64UrlDecode(jwk.y), usage: CngKeyUsages.KeyAgreement);
string token = Jose.JWT.EncodeBytes(System.Text.Encoding.UTF8.GetBytes(encryptValue), publicECCKey, JweAlgorithm.ECDH_ES, JweEncryption.A256GCM);
return token;
}
public static string Decrypt(string encryptedValue)
{
JsonTextReader reader = new JsonTextReader(new StringReader(stringkey));
var jwk = JsonSerializer.CreateDefault().Deserialize<JWK>(reader);
var publicECCKey = EccKey.New(WebEncoders.Base64UrlDecode(jwk.x), WebEncoders.Base64UrlDecode(jwk.y), WebEncoders.Base64UrlDecode(jwk.d), usage: CngKeyUsages.KeyAgreement);
string token = Jose.JWT.Decode(encryptedValue, publicECCKey, JweAlgorithm.ECDH_ES, JweEncryption.A256GCM);
return token;
}
}
public class JWK
{
public string alg { get; set; }
public int? created_at { get; set; }
public string crv { get; set; }
public int? expired_at { get; set; }
public string kid { get; set; }
public string kty { get; set; }
public string use { get; set; }
public string x { get; set; }
public string y { get; set; }
public string d { get; set; }
}
Java解密字符串生成:
String encryptedFromDotNet= "eyJhbGciOiJFQ0RILUVTIiwiZW5jIjoiQTI1NkdDTSIsImVwayI6eyJrdHkiOiJFQyIsIngiOiJBWEVBdzR6MmpnRmkzRktXZ3IwNHQwS3VwOEVOeGpJaWE3aDNVQ1BZSGpwODdwMXpxMHBHVUxXVUxNaFUzOVdubERJLTFFMEl5Mzd6WmJ3LVYzQ0pURFpsIiwieSI6IkFIMUtWOWpONG9JTEpzLThGYlJmVDNVWXF3MnJDVFVZd3k5MEYwQXFFa0VZam1KOXlyekdKVC0zTGQtOUZPRUQwZV9tcE5iYlhRVk12Q25GTEQwQTdSNzIiLCJjcnYiOiJQLTUyMSJ9fQ..AXWgvsa6PwWPSS1l.UxfvMIekKvBAMbs.1n9dqJvPZQfM8v2XEkLLQg";
String decryptedValue = getDecryptedValue(encryptedFromDotNet);
System.out.print(decryptedValue);
}
public static String getDecryptedValue(String encryptedFromDotNet ) {
try {
String ecdhKey = "{\n"
+ "\t\"kty\": \"EC\",\n"
+ "\t\"d\": \"AaDyXhcUwH90OvzbYJvocSl7uYlZNRZvgj8yesGjtqUWfxmN50NIFfnBpKohNc3wkYqviScjevczATzibw0Cnlgp\",\n"
+ "\t\"crv\": \"P-521\",\n"
+ "\t\"x\": \"AeyTJd9u-0k3ihg5T1OKqc7xlfn-a5WWTwp0yeQLz03lTHotMhiuKYQGez5KgeuODtOyZNmNdcKN6WjlFuMmVlTd\",\n"
+ "\t\"y\": \"AGum7Ok3MsKuMfrGtYUoeRq09oXwuO5yiMcxDjPbZglLKaZK-Z_kGt3ZcakVavLx46ieXw4agldm9qV6KmBCf6d7\"\n"
+ "}";
ECKey ecKey = ECKey.parse(ecdhKey);
JWEObject jweObjectServer = EncryptedJWT.parse(encryptedFromDotNet);
ECDHDecrypter decrypter = new ECDHDecrypter(ecKey.toECPrivateKey());
jweObjectServer.decrypt(decrypter);
return jweObjectServer.getPayload().toString();
} catch (Exception e) {
System.out.println(e.getMessage());
}
return null;
}
解决方案
推荐阅读
- mysql - MySQL:基于另一个并不总是具有匹配值的连接表进行排序
- android - 如何为 Launcher3 默认工作区设置最喜欢的应用程序 - Android Source
- css - 将图像放入使用纯 CSS 完成的基本梯形?
- c++ - 将 ProcessEntry32.szExeFile 与用户输入的数据进行比较时,C++ _wcsicmp 代码未编译
- javascript - 你如何让用户在 html 中为 select 标签选择默认值?
- php - 如何在 linux 上的 git hook 中重新启动进程
- sql - 如何从错误消息sql server中查找表名和列名
- javascript - 在循环中调用 resolveLocalFileSystemURL
- git - Git提交然后签出和签出然后提交之间有区别吗?
- c# - 如何使用 philips 强大的散列算法使用 C# 提取 32 位音频指纹?