2020年5月9日星期六

JWT 使用加密算法RS256 非对称加密解密

JWT 使用加密算法RS256 非对称加密解密


参考文档:

https://gist.github.com/ssippe/8fc11c4d7e766e66f06db0431dba3f0a
https://github.com/dvsekhvalnov/jose-jwt

https://mac-blog.org.ua/dotnet-core-firebase-jwt/

 

需要引用如下包: jose-jwt (version=2.5.0)、BouncyCastle 版本不限

加密和解密方式为:私钥加密、公钥解密  

生成私钥、公钥可以利用openssl工具、也可以通过在线上工具生成

私钥:

-----BEGIN PRIVATE KEY-----MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMu4IDG1XU6a7bXo4V1jSnbKk9Eum2WguAyq+maCRcP9JoHlE/HmhPOjl91aN5gDHw3pgB7QMMkPkuyY0aG9UiIo7PbBgjXsNBErprKa8G7GKhDN4B3m8jxEi1NLtCk2H8AEf8H/deGFXCdefjQx0NDEDcTbJ8STfbsqrLhOq2xzAgMBAAECgYEAg1kZMNOd8IOFxqb7P2o4ZbUhb1rciL8CS/CleBiAgOgkvtWDcZFOoYQV83sqoxFIIYEuwS88dTZcZb32U5EsdYExJvJwAAYnzpch/YAz0llvXSHzZwNfGGvs4qt0d74bFpPfveli82wSKMlykeajP2RoRQpOniTYOWrJ01UHdUECQQDt1KTj/Xs5BNmEZAkJVmGekQROADk+ztceAe9UMj/Js5xECdXVwuFh2Rm62MMQNNoW2Pjz4Y5NqhjRu0MMZnlTAkEA20hZsgA78aqTO7s++y/CLgP3Cd7uG/5RkcmjBWq2eXkt6wmazZl0BMYb7vshblnMjFXJwuOmfBJl7rTr1fg8YQJAEo4Jg0QObgdj1QFc9x6HJTDZLiC0VqMag1vRSTdWZK0fnutJhJDctp6SdFJe/Y+yCCBLY/OP/50qrIo4k+oWwwJAIn8hTTVoOL6C5xSv9cgvnhmVlYHyp4i8wFieQs3k4vtDVARwzANmExIvdssfGUMbQMCGOxihKkeirYjcyQ6CQQJAbsbpzCjDwd9JCogmTu/xYqtL898ek7LeNkhgIY2KhYtlptxlHfzgLBUgiSTNTcD1YWtSSp6uA5ImxrryDYPmfg==-----END PRIVATE KEY-----

公钥:

-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDLuCAxtV1Omu216OFdY0p2ypPRLptloLgMqvpmgkXD/SaB5RPx5oTzo5fdWjeYAx8N6YAe0DDJD5LsmNGhvVIiKOz2wYI17DQRK6aymvBuxioQzeAd5vI8RItTS7QpNh/ABH/B/3XhhVwnXn40MdDQxA3E2yfEk327Kqy4TqtscwIDAQAB-----END PUBLIC KEY-----

核心代码:

  /// <summary>  /// JWT-RS256 加密  /// 私钥加密,公钥解密  /// </summary>  /// <param name="payload">负荷部分,存储使用的信息</param>  /// <param name="privateKey">私钥</param>  /// <returns></returns>  public static string JwtEncryptRS256(IDictionary<string, object> payload, string privateKey)  {   //可以扩展header   //var headers = new Dictionary<string, object>()   //{   //  { "typ", "JWT" },   //  { "cty", "JWT" },   //  { "keyid", "111-222-333"}   //};   using (var rsa = GetRSACryptoServiceProvider(privateKey, true)) //读取私钥   {    var token = Jose.JWT.Encode(payload, rsa, Jose.JwsAlgorithm.RS256);    //var token = Jose.JWT.Encode(payload, rsa, Jose.JwsAlgorithm.RS256, headers); //带header    return token;   }  }  /// <summary>  /// JWT-RS256 解密  /// </summary>  /// <param name="token">要解密的token</param>  /// <param name="publicKey">公钥</param>  /// <returns></returns>  public static Dictionary<string, object> JwtDecryptRS256(string token, string publicKey)  {   try   {    using (var rsa = GetRSACryptoServiceProvider(publicKey, false)) //读取公钥    {     var payload = Jose.JWT.Decode<Dictionary<string, object>>(token, rsa);     return payload;    }   }   catch (Exception ex)   {    return null;   }  }  /// <summary>  /// 根据 私钥 or 公钥 返回参数  /// </summary>  /// <param name="key">私钥 or 公钥</param>  /// <returns></returns>  private static RSACryptoServiceProvider GetRSACryptoServiceProvider(string key, bool isprivate)  {   try   {    RSAParameters rsaParams;    if (isprivate)    {     using (var sr = new StringReader(key))     {      // use BouncyCastle to convert the key to RSA parameters      //需要引用包 BouncyCastle      var pemReader = new PemReader(sr);      var keyPair = pemReader.ReadObject() as RsaPrivateCrtKeyParameters;      if (keyPair == null)      {       //没有读到Privatekey      }      rsaParams = DotNetUtilities.ToRSAParameters(keyPair);     }    }    else    {     using (var sr = new StringReader(key))     {      var pemReader = new PemReader(sr);      var keyPair = pemReader.ReadObject() as RsaKeyParameters;      if (keyPair == null)      {       //没有读到Publickey      }      rsaParams = DotNetUtilities.ToRSAParameters(keyPair);     }    }    var rsa = new RSACryptoServiceProvider();    rsa.ImportParameters(rsaParams);    return rsa;   }   catch (Exception ex)   {    throw;   }  }

测试:

  static void Main(string[] args)  {   string publicKey = File.ReadAllText(@"D:\Square\openssl\bin\rsa_public_key.pem");   string privateKey = File.ReadAllText(@"D:\Square\openssl\bin\rsa_private_key.pem");   int timestamp = TimeHelper.GetTimeStamp(DateTime.UtcNow.AddSeconds(5)); //时间戳    var payload = new Dictionary<string, object>   {    {"iss","123456"},    {"exp",timestamp} //5s   };   var gettoken = JosejwtHelper.JwtEncryptRS256(payload, privateKey); //私钥加密   Console.WriteLine("加密结果:" + gettoken);   Console.WriteLine("....");   var getvalue = JosejwtHelper.JwtDecryptRS256(gettoken, publicKey); //公钥解密   Console.WriteLine("解密结果:" + JsonConvert.SerializeObject(getvalue));  }

测试结果:

 


没有评论:

发表评论