2025年度大学入学共通テスト 情報I 第1問 問1 a デジタル署名

プログラミング

2025年1月19日に2025年度大学入学共通テストにおいて情報Iの出題がなされました。

最初の問題、第1問 問1 aはデジタル署名の問題でした。

デジタル署名については公開鍵暗号、デジタル証明書とともにEx-Gramプログラミング教室の上級Dコースでズバリ詳しく説明しています。

以下にデジタル署名について解説します。

文章をネットワークを介して送信者から受信者へ送るとき、受信者としてはその文章が確かに送信者から送られた文章であること、文章が改ざんされてないことを保証したいことがあります。これを実現するのがデジタル署名であり、その文章に対して文章固有の署名をするものです。

デジタル署名の大まかな仕組みを説明しましょう。

 

送信者は

1.送信したい文章をハッシュ関数でハッシュ化します。ハッシュ化とは、ある関数で文章の要約を作成するもので、得られた結果はハッシュ値と呼ばれます。

2.次にハッシュ値を署名鍵(秘密鍵)で暗号化します。これが署名です。

3.そして相手に送信文と署名を送ります。送信文は暗号化していない平文でも構いません。

 

受信者は

1.受信した文章をハッシュ関数でハッシュ化します。このハッシュ値をAとします。

2.次に署名を検証鍵(公開鍵)で復号します。得られたハッシュ値をBとします。

 

AとBが等しいことが確認できれば、確かに送信者から送られた文章であることと、受信文が改ざんされてないことがわかります。

 

以上のことをRSA暗号を用いてPythonプログラムで試してみましょう。

 

送信者が2つの素数p、qと値e、dを用意します。そして、素数p、q を掛けた数 p×q を法とする世界を考えます。以下では、説明のために小さな素数を用いています。

Aさんは受信者のBさんに検証鍵であるeとp×qを送ります。

 

 

p, q = 193, 11  # 素数
e = 77   # 検証鍵(公開鍵)
d = 773  # 署名鍵(秘密鍵)
n = p * q  # nを法とする世界

 

送信者は送信したい文章をハッシュ関数でハッシュ化します。ハッシュ関数としてはSHA-256がよく用いられますが、ここでは説明のために簡易的な独自のハッシュ関数を用いて要約することにします。例えば、リストの要素の数値を掛け合わせて、その結果をn = p * qで割ったものをハッシュ値としてみます。

 

import numpy as np

# 送信文
org = [13, 16, 246, 21, 65, 32]

# 送信分の要約を作る
my_hash = 1
for i in org:
    my_hash *= i
my_hash %= n

print("送信文のhash値", my_hash)

 

送信者は次にハッシュ値を署名鍵(秘密鍵)dで暗号化します。これが署名となります。

 

# 署名鍵(秘密鍵)で暗号化

crp = pow(my_hash, d, n)  # pow(x, y, z)はxのy乗に対するzの剰余を返す
print("署名(hash値の暗号文)", crp)

 

送信者は送信文にhash値の暗号文(署名)をつけて送信します。

 

次に受信者側の確認手順を見ていきましょう。

まずは、受信者が受け取ったものを整理しましょう。受信文と送信者がつけた署名を受け取り、検証鍵は公開されています。

 

# 受け取ったもの
print("受信文", org)  # 受信文
print("送信者の署名", crp)  # 署名(hash値の暗号文)

# 公開されているもの
print("送信者の検証鍵", e)  # 検証鍵

 

受信者は受信した文章を先ほどと同じハッシュ関数でハッシュ化します。このハッシュ値をAとします。

 

# 受信分の要約を作る
my_hash = 1
for i in org:
    my_hash *= i
my_hash %= n

print("受信文のhash値", my_hash)

 

次に署名を検証鍵(公開鍵)eで復号します。得られたハッシュ値をBします。

 

# 検証鍵(公開鍵)でhash値の暗号文を復号
decrp = pow(crp, e, n)  # pow(x, y, z)はxのy乗に対するzの剰余を返す
print("復号したハッシュ値", decrp)

 

ハッシュ値A(my_hash)とハッシュ値B(decrp)が等しいかどうかを確認します。

 

my_hash == decrp

 

ハッシュ値B(decrp)が正しく復号できたということは署名鍵(秘密鍵)を持っている人から送信されたと言えます。また、ハッシュ値B(decrp)が受信文のハッシュ値A(my_hash)と等しいことから、受信文は送信者から送られた文章であり改ざんされてないことがわかります。

 

なお、以上では公開鍵暗号方式としてRSA暗号をもとに説明してきましたが、ブロックチェーンなどでは公開鍵暗号方式として楕円曲線暗号が用いられています。