質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

暗号化

ネットワークを通じてデジタルデータをやり取りする際に、第三者に解読されることのないよう、アルゴリズムを用いてデータを変換すること。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

ハッシュ

ハッシュは、高速にデータ検索を行うアルゴリズムのことです。

Q&A

解決済

1回答

3597閲覧

C# のコード内文字列の文字コードとHMAC SHA1でのハッシュ化について

退会済みユーザー

退会済みユーザー

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

暗号化

ネットワークを通じてデジタルデータをやり取りする際に、第三者に解読されることのないよう、アルゴリズムを用いてデータを変換すること。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

ハッシュ

ハッシュは、高速にデータ検索を行うアルゴリズムのことです。

0グッド

0クリップ

投稿2018/11/07 10:41

文字列を秘密鍵を用いてHMAC SHA 1でハッシュ化した後にBASE64エンコードしてから最後にURLエンコードするとゆうプログラムが正しく動いているかを検証しています。ソースコードは下の通りです。
C#内で定義された文字列の文字コードはUnicodeであるとネットにありましたので文字列をUnicodeエンコーディングオブジェクトでバイト配列に変換→ハッシュ化→BASE64エンコード→URLエンコードしました。

var signature = ""; var unicode_encoding = new UnicodeEncoding(); Byte[] StringToSignByte = unicode_encoding.GetBytes("apikey=apikeysample&command=deployvirtualmachine&serviceofferingid=38&templateid=241&zoneid=1"); Byte[] AccesKeyIDByte =unicode_encoding.GetBytes("SECRETKEYSAMPLE"); Byte[] hashBytes; using (HMACSHA1 hash = new HMACSHA1(AccesKeyIDByte)) { hashBytes = hash.ComputeHash(StringToSignByte); signature=HttpUtility.UrlEncode(Convert.ToBase64String(hashBytes)); } Console.WriteLine("Signature:" + signature);

結果はこのようになりました。検証のためにunicodeエンコーディング以外も使用してハッシュ化しました。

Unicodeエンコーディング: y5Pic9g9nppPCcK1HTEh3MvUyXw%3d UTF8エンコーディング: 8vjVFWLtIruwxdxNvG1CLs1mGVw%3d Shift-JISエンコーディング:8vjVFWLtIruwxdxNvG1CLs1mGVw%3d ASCIIエンコーディング: 8vjVFWLtIruwxdxNvG1CLs1mGVw%3d

こちらのサイトの一番下に正しい答えの結果があります。

秘密鍵:SECRETKEYSAMPLE 文字列:apikey=apikeysample&command=deployvirtualmachine&serviceofferingid=38&templateid=241&zoneid=1 答え:8vjVFWLtIruwxdxNvG1CLs1mGVw%3D

あれれ・・・・2つ疑問点が生まれました。
①Uncodeのエンコーディングのみ他と値が全然違うが他のエンコーディングでの値は一致している
②最後のdが小文字で答えと一致しない

みなさんの環境では答えのような結果になりますか。
また、なぜこのような検証結果になったのでしょうか。
有識者の方いましたらご教示いただけると幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

文字列が半角英数字のみの場合、UTF8, Shift-JIS, ASCII は一致します。
また、%3d と %3D は同じです。

投稿2018/11/07 10:58

Zuishin

総合スコア28660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2018/11/07 11:02

一致するのは、他の二つのエンコーディングが ASCII に互換性を持たせた結果です。 また %3d は文字コード 3d の文字(=)を表します。
退会済みユーザー

退会済みユーザー

2018/11/07 11:06

回答ありがとうございます。同じなんですね。 この場合だとUnicode以外でエンコードしたバイト配列が結果と一致することになりますよね。秘密鍵と文字列はソースコード内で定義しているからその文字コードはUnicodeであってバイト配列へ変換する際はUnicodeのエンコーディングオブジェクトを使うべきだと思ったのですが...その考えは間違っているのでしょうか。
Zuishin

2018/11/07 11:15

何が問題なのかよくわかりません。元々の文字コードがどうあれ、最終的に ASCII エンコーディングになっているので、同じ文字列が同じ結果になったという至極そうあるべき結果です。
Zuishin

2018/11/07 11:20 編集

たとえば、テキストファイルで ABCDEFG というテキストを作り、UTF8, Shift-JIS, ASCII のそれぞれのエンコーディングで保存してみてください。 テキストエディタで編集している間は文字列は Unicode で表されているはずですが、保存した時点でそれぞれのエンコーディングになります。 保存したら、その三つのファイルをバイナリエディタなどで比較してみてください。 BOM が無ければ完全に一致するはずです。
Zuishin

2018/11/07 11:22

そして Unicode エンコーディングは、実は UTF16LE エンコーディングです。 これは ASCII と互換性がありません。 だから一つだけ違う結果になります。
退会済みユーザー

退会済みユーザー

2018/11/07 11:39

なるほど....ASCIIが基準で他のエンコーディングが互換性を持たせたのですね。 エンコードの際はエンコードされる文字列と同じ文字コードでエンコードするべきだと思っていました。 ありがとうございました。
Zuishin

2018/11/07 11:41

> エンコードの際はエンコードされる文字列と同じ文字コードでエンコードするべき 読んでみておかしくありませんか? エンコードというのは文字にコードを割り当てるという意味です。
退会済みユーザー

退会済みユーザー

2018/11/10 10:05

すごく大きな勘違いをしていたことに気づきました...ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問