「rsa」タグアーカイブ

RSA暗号

今回はRSA暗号です。

RSA暗号の概要

発明
1977年にロナルド・リベスト、アディ・シャミア、レオナルド・エーデルマンによって発明されました。名前は発明者の頭文字から取られています。

背景
RSA暗号は、1976年に公開鍵暗号の概念を提唱したディフィーとヘルマンの研究を受けて、実用的なアルゴリズムとして具体化されました。

原理
RSAはフェルマーの小定理に基づいています。これは、特定の数学的性質を利用して、暗号化と復号化を行う方法です。

特許と公開
RSAは1983年に特許が取得され、RSA Security社が独占していましたが、特許が2000年に満了し、以降は誰でも自由に使用できるようになりました。

使い方

RSA暗号は以下の用途に使われます:

  • 秘匿: データを暗号化して第三者に解読できないようにします。
  • 認証: デジタル署名を用いてデータの信頼性を保証します。

RSAは公開鍵暗号の一つで、暗号化と復号化に異なる鍵を使用することが特徴です。公開鍵で暗号化したデータは、対応する秘密鍵でしか復号できません。

RSA暗号の基本的な仕組み

RSA暗号は、「大きな素数の積を素因数分解することが非常に難しい」という数学的な性質に基づいています。RSAは公開鍵(暗号化に使用)と秘密鍵(復号化に使用)の2つの鍵を使います。公開鍵は誰でも知ることができますが、秘密鍵は鍵の所有者だけが知っているべきものです。

1. 鍵の生成

RSA暗号で使用される公開鍵と秘密鍵は、以下の手順で生成されます。

  • 大きな素数を2つ選ぶ:
    非常に大きな素数 p と q を選びます(通常は数百桁の素数を使います)。
  • これらを掛け合わせる:
    n = p × q として、積 n を計算します。n は公開鍵の一部になります。
  • オイラーのトーシェント関数を計算:
    ϕ(n) = (p − 1) × (q − 1) を計算します。これは、公開鍵を生成するための中間計算に使います。
  • 公開鍵の指数 e を選ぶ:
    1 < e < ϕ(n) かつ e と ϕ(n) が互いに素であるような e を選びます。e は通常、公開鍵として広く使われる数値である65537が選ばれることが多いです。
  • 秘密鍵の指数 d を計算:
    e × d ≡ 1 (mod ϕ(n)) を満たすような d を計算します。この d が秘密鍵になります。

2. 暗号化

メッセージ M を暗号化するには、以下の手順を使います。

  • 公開鍵を取得:
    公開鍵 (n, e) は公開されているので、誰でも取得できます。
  • メッセージを暗号化:
    メッセージ M を次のように暗号化します:
    C = M^e mod n
    ここで、C は暗号文です。

3. 復号化

暗号文 C を復号化して元のメッセージ M を取得するには、以下の手順を使います。

  • 秘密鍵を使用:
    秘密鍵 (d) を使って暗号文 C を次のように復号化します:
    M = C^d mod n
    これにより、元のメッセージ M を得ることができます。

Python

このサンプルはわかりやすくする為にセキュリティ向上させる機能は省いています。

from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA

def generate_keys(keysize=2048):
    """RSA暗号の鍵ペアを生成する"""
    # 鍵ペアを生成
    key = RSA.generate(keysize)
    public_key = key.publickey()
    return public_key, key

def encrypt(plaintext, public_key):
    """平文を暗号化する"""
    # PKCS#1 OAEPパディングを用いて暗号化
    cipher = PKCS1_OAEP.new(public_key)
    ciphertext = cipher.encrypt(plaintext.encode('utf-8'))
    return ciphertext

def decrypt(ciphertext, private_key):
    """暗号文を復号する"""
    # PKCS#1 OAEPパディングを用いて復号
    cipher = PKCS1_OAEP.new(private_key)
    plaintext = cipher.decrypt(ciphertext)
    return plaintext.decode('utf-8')

if __name__ == "__main__":
    # 鍵の生成
    public_key, private_key = generate_keys()

    # 公開鍵と秘密鍵をPEM形式でエクスポート
    public_key_pem = public_key.export_key().decode('utf-8')
    private_key_pem = private_key.export_key().decode('utf-8')

    # 公開鍵と秘密鍵を表示
    print("公開鍵:")
    print(public_key_pem)
    print("秘密鍵:")
    print(private_key_pem)

    # 平文
    message = "Hello, RSA!"

    # 暗号化
    ciphertext = encrypt(message, public_key)
    print("暗号文:", ciphertext)

    # 復号化
    decrypted_message = decrypt(ciphertext, private_key)
    print("復号文:", decrypted_message)

実行の概要

暗号化:

  • encrypt 関数は公開鍵を使って平文を暗号化し、暗号文をリストとして返します。

復号化:

  • decrypt 関数は秘密鍵を使って暗号文を復号化し、元の平文を返します。

実行結果

公開鍵:
—–BEGIN PUBLIC KEY—–
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtL63nW412wf+oz+b1thN
2jQxjPwTSnigTcXMYrunUMUvYLgNNePtFgoD3YyPa356xlHucuIwESVhA8X6GqTq
IiAQUw4dL/IQzoshrTi0H1gfwVtDPeUworgUYLkBnXPOigtzYT2vu6teh3LUgAUx
oCbj2q22snI3NNdF04LRK6z3z/JYEZjAEasJuLlgn6+ZvqVDXO21SjrBQ8B2Qb4O
3P89qT1E+zayVH573p2JALkgZdW4xpEEJ0KYeVXU05mlwfeH+FLQ032CqPiQxaXX
Es9W3asT/RQhgtjyrtq4qHy0iCHQ+PXJl8pjD2B+pVy24w8xG+08qxQyZTxJjOHn
NQIDAQAB
—–END PUBLIC KEY—–

秘密鍵:
—–BEGIN RSA PRIVATE KEY—–
MIIEpQIBAAKCAQEAtL63nW412wf+oz+b1thN2jQxjPwTSnigTcXMYrunUMUvYLgN
NePtFgoD3YyPa356xlHucuIwESVhA8X6GqTqIiAQUw4dL/IQzoshrTi0H1gfwVtD
PeUworgUYLkBnXPOigtzYT2vu6teh3LUgAUxoCbj2q22snI3NNdF04LRK6z3z/JY
EZjAEasJuLlgn6+ZvqVDXO21SjrBQ8B2Qb4O3P89qT1E+zayVH573p2JALkgZdW4
xpEEJ0KYeVXU05mlwfeH+FLQ032CqPiQxaXXEs9W3asT/RQhgtjyrtq4qHy0iCHQ
+PXJl8pjD2B+pVy24w8xG+08qxQyZTxJjOHnNQIDAQABAoIBAAx54KtDhQCoOd2z
YZKwLhmKgkQYz00T6/7KUTwcd2VmIwnSUokegUpE6TTlA65YFen0FFlGPyqj0aFE
zGmD6ixuWaod/opFc38KUAoIsLg8KT77yXWviQ6mVbPCeXfQm1hgh3eWHjf+UYFY
fg4TLbSAErjQxlxlcWWamXWK4VzaDyNOqFtMuJ3wZL27grtJmDpbEfsYfUewd22F
PEKMluXobJ59DYkk/MCQOsazK+SiCOd95eY4GMH0xawrETRpZ0ill96GISrH8b66
EmKXxcTy89bha2jr3/x7yhG3yifuq/PXtyx7r4YIv3HuXbcXjfnOqm5whaTEKroQ
oPwu2YkCgYEAyWki7087YCUxhN7Q5Wf0OzFGReORuEzTmuBpv04sqGpuo8LhotoP
/cFEGqd8Ld9D8bOuDeOJnChBafU9HrUj9q7E6Bd+ktETaPlOtkqec3OQjLx4hJpj
ar4cTLqCs9nyrPVBAgYk8EujEZlnq/uT8VPCbEgD7yJFWoXiRkJvtWkCgYEA5bux
ZJouaNd+RsdcTzOyDzOPRVWRVODlU0sJw66p6771IdWgNIRovOQYtBiA+VqW81TO
ce+w86wDbIOS2rvqdfycbuSMyUhz45OFLThmK+HeIZ0LcJhkdr6jSvicN5V96WHO
D9xCJ/zl1JH7DMijku74xoT/uNdoiuzJKtgHre0CgYEAnoxa6dOPRAJDVvsnqk8I
3UfOr9mSrmgb80FRPT1GvlT6P4N7p3zNNc5b1Def82Rb0frFuz0w6HJv+/8HXBLv
+pJdgu5rvxtCklIe+jUHQo7obUE4Bfqa5D4/fM8dcILTG//8aqF3lomUFpiSGbpz
HXf4BtEx958cxUO7ed92nHECgYEAwwQGvWDIvsUXc9vud2lp4M+i8neFzGixI3jS
jCNsKSxMCPHAcnRoONjkQ5V9fq8w7tTx/vQ64U8HBQnYEwhsKsZKwTQQcxmnDuv+
pHl4+g1dtGkM+gLTXZ3NHmpWqjSj0wbslrgiDLH5I+7cD2kOuj9UPalPL0jkfPIu
fskuE60CgYEAjH35EyLtjamA0nYf87xk6YNLqrzfWK7SgCaubrMbNWw3G5r0j293
GNUAq/hlydJR6yOleOTRUOns3SFxH7ks1MEen+M0Tq60jMWw+HEmRQy9c1AxiwYL
VdcVhkzFoGwqWUXDiSbN6cmiNkgh8IVJL4Xss2Z6HtB+a/ws5qiIrRA=
—–END RSA PRIVATE KEY—–

暗号文:b”\\\nB}k\x0bQ\x95\x01\x8c\xa2\x02z\x1b\xaa\xd21\t\xac\xb9\xf4\xe0WK\xb4’P\tx\xaf\x81\x1f\xbd,F\t\xb2\x8b\xd9y\xff\x18\xc1\x80\x96\xa2\xb0\xcb\xaeAQpv\xcfW\x18\xd9\xbe4:\xe6\xd1y\xf3\xd4\xe0U\x8ft\x10\xcd\xf2’Jl\x97\xb5\xf7\x1dtE\x0c<\xa8\xbeB&G3\x92\x15\xfcD\xe7%\xc9\xaeEn\x01\x87\xc2\xad&Oy]:\xbe.\xb0\xb2\xdf\x1c+q6\x96\xeb\xea\x90\xcf\xd5\xfa\x8b\xa7\xd7\x9af!.\x1c4oX\xbbKU\x9f\xbb\xe9x^\x7f\x9e\x92\x86\xcd5\xf9\xe8\xb9D\x0eB3\xe6\xd8\rZLD\xed\xee\xe0\xc5\x13\xa9J8/\\\xf5\xf0\xb4\xddS\xbb\x12\xf7m(\x8b\xe8\xb0\x18@\x94w`\xb7\xd0\x8f[l\x0e\x8a\x10\x91\xc4\x8d\x1f\x98T\xc0\xc6\x8c\x01\xcd\xbc4\xbe\xd7{\xd2\x9f\xf6,E;\xdc\xe9\x1d\x14\xda3\x1fi\xef\xb9\x85\x93\x08\xf241/\xeeB\x9eY\xb3Qi/\xa4kp#F`f\xdc\xea^\x9c"
復号文: Hello, RSA!

HTTPSのSSLキーを確認するには?public exponent?

複数年キーがあると、ゴッチャになりますよね。
申請したキーが正しい?または、サーバを設定する前に
キーを確認したい、という方。下記のコマンドを!

証明書ファイル(モジュラス)を表示するには
openssl x509 -noout -text -in ここにファイル名 -modulus

秘密鍵(秘密キー)ファイル(モジュラス)を表示するには
openssl rsa -noout -text -in ここにファイル名 -modulus

秘密鍵内と証明書内にある “modulus” 部分と “public exponent”
部分は完全に一致しなければなりません。
public exponentがpublicの下の何行目かにexponentと書いてある場合があります。

ファイルの同期 rsync(+ssh)  注意:Bad configuration option: AuthorizedKeysFile

rsync(+ssh)でバックアップをする。
CentOS

tekitouser1@local1からtekitouser2@remoto2に/var/www/htmlをrsync(+ssh)で取りに行く。

★送信先のサーバ作業(ホスト名:remoto1):
■sshの設定ファイル作成
# vi /etc/ssh/ssh_config に下記を追加。

RSAAuthentication yes
PubkeyAuthentication yes

#注意 AuthorizedKeysFileの指定をすると書いてあるページがあるが、
#/etc/ssh/ssh_config: line 46: Bad configuration option: AuthorizedKeysFile
#のエラーになります。
#man ssh で見る限り、この指定(option)はない。ファイルは ~/.ssh/authorized_keysに書く。

■ssh再起動
/etc/init.d/ssh restart

★送信元のサーバ作業(ホスト名:local1)
■rsa ファイルを作る
# su -l tekitouser1
$ ssh-keygen -t rsa
問い合わせにはすべてenter

■公開ファイルを送信先にコピー
$ scp /home/tekitouser1/.ssh/in_rsa.pu tekitou2@remoto1:/home/tekitouser2/.ssh/

★送信先のサーバ作業(ホスト名:remoto1):
■公開キーファイルをssh指定のファイルに変更
#su -l tekitouser2
$ cd .ssh
$ cp id_rsa.pub authorized_keys

★送信元のサーバ作業(ホスト名:local1)
■実際のテスト
# su -l tekitouser
$ ssh tekitouser2@remoto1
で自動ログインできるか確認。
出来たら,logoutして、送信元に戻ってください。

■実際に送る。
# su -l tekitouser
$ rsync -avz -e ssh tekitouser2@remoto:/var/www/html/ /var/www/html/
実際に取りに行けかを確認してください。
元ファイルが削除されたら、削除するオプションは–deleteですが、あまりおススメしません。