c# - 解密的 Json Web 令牌数据中的奇怪字符
问题描述
我正在加密SymmetricCryptograper
我放入 JWT 的用户信息。但是,当我用加密信息回调该令牌并尝试解密这些信息时,我得到了奇怪的字符。
所以,我在StackOverflow上运行,发现真正的问题可能与缺少有关,所以Encoding.UTF8
我将它们放在StreamWriter
和方法中。但是,不幸的是,这并没有奏效。StreamReader
Encrypt
Decrypt
这是我的课程,其中包含 Encrypt 和 Decrypt 方法。
public class DESCryptographer : SymmetricCryptographer
{
private readonly DESCryptoServiceProvider _des = new DESCryptoServiceProvider();
public DESCryptographer(string key) : base(key)
{
_des.GenerateIV();
IV = _des.IV;
}
public DESCryptographer(string key, string iV) : base(key, Encoding.UTF8.GetBytes(iV))
{
}
public override string Encrypt(string plainText)
{
MemoryStream memoryStream = new MemoryStream();
ICryptoTransform cEncryptor = _des.CreateEncryptor(Encoding.UTF8.GetBytes(Key), IV);
CryptoStream cryptoStream = new CryptoStream(memoryStream,
cEncryptor, CryptoStreamMode.Write);
StreamWriter writer = new StreamWriter(cryptoStream, Encoding.UTF8);
writer.Write(plainText);
writer.Flush();
cryptoStream.FlushFinalBlock();
writer.Flush();
return Convert.ToBase64String(memoryStream.GetBuffer(), 0, (int)memoryStream.Length);
}
public override string Decrypt(string encryptedText)
{
MemoryStream memoryStream = new MemoryStream
(Convert.FromBase64String(encryptedText));
ICryptoTransform cDecryptor = _des.CreateDecryptor(Encoding.UTF8.GetBytes(Key), IV);
CryptoStream cryptoStream = new CryptoStream(memoryStream,
cDecryptor, CryptoStreamMode.Read);
StreamReader reader = new StreamReader(cryptoStream, Encoding.UTF8);
return reader.ReadToEnd();
}
}
以下是我发布 JWT 的课程:
public string PublishToken(string email, string password, string digitCode, int expireMinutes, int notBeforeMinutes)
{
var hmac = new HMACSHA256();
var key = Convert.ToBase64String(hmac.Key);
var symmetricKey = Convert.FromBase64String(key);
var tokenHandler = new JwtSecurityTokenHandler();
var now = DateTime.Now;
SymmetricCryptograperManager symmetricCryptograperManager = new SymmetricCryptograperManager();
var schema = symmetricCryptograperManager.GetSymmetricCryptographer(SymmetricCryptographyStrategy.DESCryptography, "000" + digitCode);
string encryptedEmail = schema.Encrypt(email);
string encryptedPassword = schema.Encrypt(password);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Email, encryptedEmail),
new Claim(ClaimTypes.Hash, encryptedPassword),
new Claim(ClaimTypes.SerialNumber, digitCode)
}),
NotBefore = now.AddMinutes(Convert.ToInt32(notBeforeMinutes)),
Expires = now.AddMinutes(Convert.ToInt32(expireMinutes)),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(symmetricKey), SecurityAlgorithms.HmacSha256Signature)
};
var stoken = tokenHandler.CreateToken(tokenDescriptor);
var token = tokenHandler.WriteToken(stoken);
return token;
}
最后,下面是我的令牌认证类。
public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
{
SymmetricCryptograperManager symmetricCryptograperManager = new SymmetricCryptograperManager();
HttpRequestMessage request = context.Request;
AuthenticationHeaderValue authorization = request.Headers.Authorization;
if (authorization == null)
{
return;
}
if (authorization.Scheme != "Basic")
{
return;
}
if (String.IsNullOrEmpty(authorization.Parameter))
{
context.ErrorResult = new AuthenticationFailureResult("Missing Credentials", request);
return;
}
byte[] credentialBytes;
string parameter = authorization.Parameter;
string[] converted = parameter.Split('.');
credentialBytes = Convert.FromBase64String(converted[1]);
Encoding encoding = Encoding.UTF8;
encoding = (Encoding)encoding.Clone();
encoding.DecoderFallback = DecoderFallback.ExceptionFallback;
string decodedCredentials;
decodedCredentials = encoding.GetString(credentialBytes);
if (String.IsNullOrEmpty(decodedCredentials))
{
return;
}
int colonIndex = decodedCredentials.IndexOf(':');
if (colonIndex == -1)
{
return;
}
string[] colonArray = decodedCredentials.Split('"');
string encrpytedEmail = colonArray[3];
string encryptedPassword = colonArray[7];
string digitCode = colonArray[11];
var schema = symmetricCryptograperManager.GetSymmetricCryptographer(SymmetricCryptographyStrategy.DESCryptography, "000" + digitCode);
string email = schema.Decrypt(encrpytedEmail);
string password = schema.Decrypt(encryptedPassword);
Tuple<string, string> emailAndPassword = new Tuple<string, string>(email, password);
//authentication codes continues..
}
我在这些类上设置了断点,以检查我发送到数据库和从数据库接收的加密数据是否相同。是的,它们是一样的。
这是我从中得到的schema.Decrypt(encrpytedEmail)
:h\0��\u0018���547@gmail.com 预期为:ozgur547@gmail.com
提前致谢!
解决方案
您没有正确实施 IV 处理。您真的不想重用加密算法,或者XCryptoServiceProvicer
也没有必要。只要记住密钥,您就可以生成另一个轻量级对象。IV应该与密文一起存储;目前第一个明文块表示加密/解密期间使用的不同 IV 值。
当然,DES 不是现代密码学原语。试试 AES。我可以尝试并开始解释加密以及如何在协议中描述您的代码以抵御特定攻击场景中的攻击,但这对于 StackOverflow(或者我的时间,就此而言)来说太多了。
谨防仅存在的包装类,以将您对加密的理解放入代码中;稍后您肯定会想知道为什么首先要编写它们。
推荐阅读
- routes - Nuxt 子域路由
- python - 在 Python 中添加列表与扩展列表
- javascript - 如何访问函数对象中的函数?
- azure - 如何在azure数据流中处理excel
- python - python http请求(requests.get)已停止工作
- ios - 重新加载部分后无法取消选择 tableView 行
- c# - 无法为我的控制器解决类型错误的服务
- mysql - Windows 应用程序使用什么数据库,在应用程序启动时运行?
- apache-camel - Camunda 与 camunda-bpm-camel 社区版的集成删除了路由之间的交换属性集
- python - 暂停任务队列