RS256 против HS256: в чем разница?
Я использую Auth0 для обработки аутентификации в веб-приложении. Я использую ASP.NET Core v1.0.0 и Angular 2 rc5, и я не знаю много о аутентификации/безопасности в целом.
на Auth0 docs for ASP.NET Core Web Api, есть два варианта для алгоритма JWT, являющегося RS256 и HS256. Это может быть глупый вопрос, но:
в чем разница между RS256 и HS256? Каковы некоторые варианты использования (если применимо)?
3 ответа:
оба варианта относятся к тому, какой алгоритм использует поставщик удостоверений для знак JWT. Подпись-это криптографическая операция, которая создает "подпись" (часть JWT), которую получатель маркера может проверить, чтобы убедиться, что маркер не был изменен.
RS256 (подпись RSA с SHA-256) является асимметричный алгоритм, и он использует пару открытых / закрытых ключей: поставщик удостоверений имеет частный (секретный) ключ, используемый для создания подписи, и потребитель JWT получает открытый ключ для проверки подписи. Поскольку открытый ключ, в отличие от закрытого ключа, не нуждается в защите, большинство поставщиков удостоверений делают его легко доступным для пользователей для получения и использования (обычно через URL метаданных).
HS256 (HMAC С SHA-256), с другой стороны, это симметричного алгоритма, только с одним (секретным) ключом, который является делится между двумя сторонами. Поскольку один и тот же ключ используется как для создания подписи, так и для ее проверки, необходимо позаботиться о том, чтобы ключ не был скомпрометирован.
Если вы будете разрабатывать приложение, потребляющее JWTs, вы можете безопасно использовать HS256, потому что у вас будет контроль над тем, кто использует секретные ключи. Если, с другой стороны, у вас нет контроля над клиентом, или у вас нет способа защитить секретный ключ, RS256 будет лучше соответствовать, так как потребитель должен знать только открытый (общий) ключ.
Auth0 предоставляет конечные точки метаданных для протоколов OIDC, SAML и WS-Fed, где могут быть получены открытые ключи. Вы можете увидеть эти конечные точки в разделе "Дополнительные настройки" клиента.
конечная точка метаданных OIDC, например, принимает форму
https://{account domain}/.well-known/openid-configuration
. Если вы перейдете по этому URL-адресу, вы увидите объект JSON со ссылкой наhttps://{account domain}/.well-known/jwks.json
, который содержит открытый ключ (или ключи) от счет.Если вы посмотрите на образцы RS256, вы увидите, что вам не нужно настраивать открытый ключ в любом месте: он автоматически извлекается платформой.
в криптографии используются два типа алгоритмов:
симметричные алгоритмы
один ключ используется для шифрования данных. При шифровании с помощью ключа данные могут быть расшифрованы с помощью того же ключа. Если, например, Мэри шифрует сообщение с помощью ключа "my-secret" и отправляет его Джону, он сможет правильно расшифровать сообщение с помощью того же ключа "my-secret".
асимметричные алгоритмы
два ключи используются для шифрования и расшифровки сообщений. Хотя один ключ(открытый) используется для шифрования сообщения, другой ключ(закрытый) может использоваться только для его расшифровки. Таким образом, Джон может генерировать как открытые, так и закрытые ключи, а затем отправлять только открытый ключ Мэри для шифрования ее сообщения. Сообщение можно расшифровать только с помощью закрытого ключа.
сценарий HS256 и RS256
эти алгоритмы не используются для шифрования / декритирования данных. Скорее они используются для проверки происхождение или подлинность данных. Когда Мэри нужно отправить открытое сообщение Jhon, и он должен убедиться, что сообщение, безусловно, от Мэри, HS256 или RS256 могут быть использованы.
HS256 может создать подпись для данного образца данных с помощью одного ключа. Когда сообщение передается вместе с подписью, принимающая сторона может использовать тот же ключ для проверки соответствия подписи сообщению.
RS256 использует пару ключей, чтобы сделать то же самое. Подпись может только генерируется с помощью закрытого ключа. А открытый ключ используется для проверки подписи. В этом случае, даже если Джек находит открытый ключ, он не может создать поддельное сообщение с подписью для олицетворения Мэри.
есть разница в производительности.
просто поставить
HS256
примерно на 1 порядок быстрее, чемRS256
для проверки, а примерно на 2 порядка быстрее, чемRS256
для выдачи (подписания).640,251 91,464.3 ops/s 86,123 12,303.3 ops/s (RS256 verify) 7,046 1,006.5 ops/s (RS256 sign)
Не зацикливайтесь на реальных цифрах, просто думайте о них по отношению друг к другу.
[программы.cs]
class Program { static void Main(string[] args) { foreach (var duration in new[] { 1, 3, 5, 7 }) { var t = TimeSpan.FromSeconds(duration); byte[] publicKey, privateKey; using (var rsa = new RSACryptoServiceProvider()) { publicKey = rsa.ExportCspBlob(false); privateKey = rsa.ExportCspBlob(true); } byte[] key = new byte[64]; using (var rng = new RNGCryptoServiceProvider()) { rng.GetBytes(key); } var s1 = new Stopwatch(); var n1 = 0; using (var hs256 = new HMACSHA256(key)) { while (s1.Elapsed < t) { s1.Start(); var hash = hs256.ComputeHash(privateKey); s1.Stop(); n1++; } } byte[] sign; using (var rsa = new RSACryptoServiceProvider()) { rsa.ImportCspBlob(privateKey); sign = rsa.SignData(privateKey, "SHA256"); } var s2 = new Stopwatch(); var n2 = 0; using (var rsa = new RSACryptoServiceProvider()) { rsa.ImportCspBlob(publicKey); while (s2.Elapsed < t) { s2.Start(); var success = rsa.VerifyData(privateKey, "SHA256", sign); s2.Stop(); n2++; } } var s3 = new Stopwatch(); var n3 = 0; using (var rsa = new RSACryptoServiceProvider()) { rsa.ImportCspBlob(privateKey); while (s3.Elapsed < t) { s3.Start(); rsa.SignData(privateKey, "SHA256"); s3.Stop(); n3++; } } Console.WriteLine($"{s1.Elapsed.TotalSeconds:0} {n1,7:N0} {n1 / s1.Elapsed.TotalSeconds,9:N1} ops/s"); Console.WriteLine($"{s2.Elapsed.TotalSeconds:0} {n2,7:N0} {n2 / s2.Elapsed.TotalSeconds,9:N1} ops/s"); Console.WriteLine($"{s3.Elapsed.TotalSeconds:0} {n3,7:N0} {n3 / s3.Elapsed.TotalSeconds,9:N1} ops/s"); Console.WriteLine($"RS256 is {(n1 / s1.Elapsed.TotalSeconds) / (n2 / s2.Elapsed.TotalSeconds),9:N1}x slower (verify)"); Console.WriteLine($"RS256 is {(n1 / s1.Elapsed.TotalSeconds) / (n3 / s3.Elapsed.TotalSeconds),9:N1}x slower (issue)"); // RS256 is about 7.5x slower, but it can still do over 10K ops per sec. } } }