今回はSHAアルゴリズムを使用してデータ保護します
SHAアルゴリズムって何?
本サイトで何度か書いているAESやRSAといった暗号化アルゴリズムの1つで不可逆性となっており、暗号化した値を復号化することができません。そのため、暗号化した値同士を比較して元になったデータが同じかどうかを判定するといった形で使用されています。また、SHAにもいくつか種類があるので詳しくは以下サイトを参照してください
-
SHA-1、SHA-2、SHA256が結局なんなのかわからないので調べた #Go - Qiita
SHA-1、SHA-256はGoの標準パッケージにも入っています。存在は知っていたものの得体が知れなくてスルーしていたの ...
続きを読む
元データを暗号化する
「System.Security.Cryptography」クラスには4種類のSHA(SHA1、SHA256、SHA384、SHA512)があり、呼び出すインスタンスを変えるだけでそれ以降は同じ処理となります
public string ComputeSHA1Hash(string data)
{
using (SHA1 sha1 = SHA1.Create())
{
byte[] hashBytes = sha1.ComputeHash(Encoding.UTF8.GetBytes(data));
return BitConverter.ToString(hashBytes).Replace("-", String.Empty);
}
}
public string ComputeSHA256Hash(string data)
{
using (SHA256 sha256 = SHA256.Create())
{
byte[] hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(data));
return BitConverter.ToString(hashBytes).Replace("-", String.Empty);
}
}
public string ComputeSHA384Hash(string data)
{
using (SHA384 sha384 = SHA384.Create())
{
byte[] hashBytes = sha384.ComputeHash(Encoding.UTF8.GetBytes(data));
return BitConverter.ToString(hashBytes).Replace("-", String.Empty);
}
}
public string ComputeSHA512Hash(string data)
{
using (SHA512 sha512 = SHA512.Create())
{
byte[] hashBytes = sha512.ComputeHash(Encoding.UTF8.GetBytes(data));
return BitConverter.ToString(hashBytes).Replace("-", String.Empty);
}
}
暗号した値を比較する
SHAは暗号化したら復号化できないので暗号化された内容お互い正しいかのチェックをする必要があります。チェックする際は、大文字小文字を区別しないオプションをつけて実施しています
public bool VerifyDataSHA1Integrity(string originalData, string computedHash)
{
string originalHash = ComputeSHA1Hash(originalData);
// 「StringComparison.OrdinalIgnoreCase」が大文字・小文字を区別しないオプション
return string.Equals(originalHash, computedHash, StringComparison.OrdinalIgnoreCase);
}
public bool VerifyDataSHA256Integrity(string originalData, string computedHash)
{
string originalHash = ComputeSHA256Hash(originalData);
// 「StringComparison.OrdinalIgnoreCase」が大文字・小文字を区別しないオプション
return string.Equals(originalHash, computedHash, StringComparison.OrdinalIgnoreCase);
}
public bool VerifyDataSHA384Integrity(string originalData, string computedHash)
{
string originalHash = ComputeSHA384Hash(originalData);
// 「StringComparison.OrdinalIgnoreCase」が大文字・小文字を区別しないオプション
return string.Equals(originalHash, computedHash, StringComparison.OrdinalIgnoreCase);
}
public bool VerifyDataSHA512Integrity(string originalData, string computedHash)
{
string originalHash = ComputeSHA512Hash(originalData);
// 「StringComparison.OrdinalIgnoreCase」が大文字・小文字を区別しないオプション
return string.Equals(originalHash, computedHash, StringComparison.OrdinalIgnoreCase);
}
実際につかってみる
それでは実際にSHAを動かして、結果を見てみましょう。対象データを2種類用意して、元データのは「original」、違うデータを「modified」としています。
結果はSHA1が文字列的に一番短く、それ以降は末尾の数字が大きくなるほどに暗号化された文字列が長くなっていきました