C# 解密的Json Web令牌数据中的奇怪字符

C# 解密的Json Web令牌数据中的奇怪字符,c#,encryption,cryptography,jwt,C#,Encryption,Cryptography,Jwt,我正在通过symmetriccryptographer加密用户信息,我将其放入JWT。但是,当我用加密的信息调用令牌并尝试解密这些信息时,我会得到奇怪的字符 因此,我运行了StackOverflow,发现真正的问题可能与缺少编码有关。UTF8因此我将它们放在StreamWriter和StreamReader方法中的实例中。但是,这并不太不幸 这是我的类,它包含加密和解密方法 public class DESCryptographer : SymmetricCryptographer {

我正在通过
symmetriccryptographer
加密用户信息,我将其放入JWT。但是,当我用加密的信息调用令牌并尝试解密这些信息时,我会得到奇怪的字符

因此,我运行了StackOverflow,发现真正的问题可能与缺少
编码有关。UTF8
因此我将它们放在
StreamWriter
StreamReader
方法中的
实例中。但是,这并不太不幸

这是我的类,它包含加密和解密方法

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..
    }
public异步任务authenticateSync(HttpAuthenticationContext,CancellationToken CancellationToken)
{
SymmetricCryptoGrapherManager SymmetricCryptoGrapherManager=新的SymmetricCryptoGrapherManager();
HttpRequestMessage请求=context.request;
AuthenticationHeaderValue authorization=request.Headers.authorization;
if(授权==null)
{
返回;
}
if(authorization.Scheme!=“基本”)
{
返回;
}
if(String.IsNullOrEmpty(authorization.Parameter))
{
context.ErrorResult=新身份验证失败结果(“缺少凭据”,请求);
返回;
}
字节[]凭证字节;
字符串参数=authorization.parameter;
string[]converted=parameter.Split('.');
credentialBytes=Convert.FromBase64String(已转换[1]);
编码=Encoding.UTF8;
encoding=(encoding)encoding.Clone();
encoding.DecoderFallback=DecoderFallback.ExceptionFallback;
字符串解码定义;
decodedCredentials=encoding.GetString(credentialBytes);
if(String.IsNullOrEmpty(decodedCredentials))
{
返回;
}
int colonIndex=decodedCredentials.IndexOf(':');
如果(克隆索引==-1)
{
返回;
}
字符串[]colonArray=decodedCredentials.Split(“”);
字符串encrpytedEmail=colonArray[3];
字符串encryptedPassword=colonArray[7];
字符串digitCode=colonArray[11];
var schema=symmetriccryptographmanager.getsymmetriccryptography(SymmetricCryptographyStrategy.desccryptography,“000”+数字代码);
字符串email=schema.Decrypt(encrpytedEmail);
字符串密码=schema.Decrypt(encryptedPassword);
元组emailAndPassword=新元组(电子邮件,密码);
//身份验证代码继续。。
}
我在这些类上设置断点,以检查发送到数据库和从数据库接收到的加密数据是否相同。是的,它们是相同的

这是我从schema.Decrypt(encrpytedEmail)
中得到的: h\0��\u0018���547@gmail.com 预计:ozgur547@gmail.com


提前感谢!

您没有正确实现IV处理。您确实不想重复使用加密算法或
XcryptoServiceProvider
,也没有必要重复使用。只需记住密钥,您就可以生成这些轻量级对象中的另一个。IV应该与密文一起存储;cur通常,第一块明文表示加密/解密期间使用的不同IV值


当然,DES不是一种现代的加密原语;试试AES。我可以试着开始解释加密,以及在特定攻击场景中如何在协议中描述您的代码,以抵御攻击,但这对于StackOverflow(或者我的时间)来说太多了

当心包装类,它们的存在只是为了将您对加密的理解放入代码中;稍后您肯定会想知道为什么要首先编写它们