LoginSignup
12
12

BouncyCastle で公開鍵暗号標準(RSA)を扱う

Last updated at Posted at 2014-05-18

キーペアを用意する

openssl コマンドで秘密鍵、公開鍵のペアを作成する

秘密鍵

$ openssl genrsa > private.pem

秘密鍵を元にした公開鍵

$ openssl rsa -pubout < private.pem > public.pem

参考: opensslでRSA暗号と遊ぶ - ろば電子が詰まっている

BouncyCastle のソースコードをプロジェクトに取り込む

以下のように Git リポジトリをクローンして必要な箇所をプロジェクトに取り込む。

$ git clone https://github.com/bcgit/bc-csharp.git

暗号化とその復号をやってみる

コードに記載されている公開鍵・秘密鍵は、このサンプル用に用意したものです。実務で利用しているものではありません。念のため :wink:

RSATest.cs
using UnityEngine;
using System.IO;
using System.Text;

using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Encodings;

public class APITestMain : MonoBehaviour {

	// (いろいろ省略)

		// RSA公開鍵で"hogehoge" を暗号化
		// その後、その公開鍵とペアとなる秘密鍵で復号する
		public void DoTest() {
			// 暗号化の対象となる文字列
			var originalText = "hogehoge";

			// 文字列からバイト列を取得
			var originalBytes = Encoding.UTF8.GetBytes(originalText);
			
			// ============
			// 暗号化
			// ============

			// 公開鍵のPEMフォーマット文字列(opensslで生成したPEM形式文字列をここに貼り付け)
			var publicKeyPem = new StringReader(@"-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAOTlsg0qJMptmM8LFqCWEC1bIcdvnzoH
xm+xscJb9qpAZhVluEKz+gTSlEGEDDHlOFjC8LcWrMfVK7vl+PR92RMCAwEAAQ==
-----END PUBLIC KEY-----
			");
			// PEMフォーマットの公開鍵を読み込んで KeyParam を生成
			var publicKeyReader = new PemReader(publicKeyPem);
			var publicKeyParam = (AsymmetricKeyParameter)publicKeyReader.ReadObject();

			// RSA暗号標準オブジェクト(PKCS#1)を生成
			var rsa = new Pkcs1Encoding(new RsaEngine());

			// RSA暗号オブジェクトを初期化(第1引数 true は「暗号化」を示す)
			rsa.Init(true, publicKeyParam);

			// 対象のバイト列を渡し暗号化した結果のバイト列を受け取る
			byte[] encrypted = rsa.ProcessBlock(originalBytes, 0, originalBytes.Length);

			// とりあえず結果を表示してみる(バイト列なので表示しきれないが一応)
			Debug.Log ("encrypted: " + encrypted);
			
			// ============
			// 復号
			// ============

			// 秘密鍵のPEMフォーマット文字列(opensslで生成したPEM形式文字列をここに貼り付け)
			var privateKeyPem = new StringReader(@"-----BEGIN RSA PRIVATE KEY-----
MIIBPAIBAAJBAOTlsg0qJMptmM8LFqCWEC1bIcdvnzoHxm+xscJb9qpAZhVluEKz
+gTSlEGEDDHlOFjC8LcWrMfVK7vl+PR92RMCAwEAAQJBANONg6ltKQG6l3/MFMao
yxzQXIDyJmzA4OM8jTlAO9MO4IOdhkkyqr4JW+2pj8ejBgyj0w55XPEir44/6ByO
ewkCIQD2SHPYKCeiEwSNo231LVqa1bK7mSDeOGuYaiKLjiwqlwIhAO3to/PuXpAc
bIAzF33A2f9pGLiIaO3jhBkDyan/GkDlAiEAyH0syQ/PS9Jdh4w+jDPyqU9D5BIB
PsYBWR81phQEAlsCIGWa7UAXVHSwXrlkmCyQtce3xuHPBxhH57qS/oTFNx3tAiEA
0PJgIm1jvfuWKN+JPcfiCRciSyO1A6LPYCQcbVRa934=
-----END RSA PRIVATE KEY-----
			");

			// PEMフォーマットの秘密鍵を読み込んで KeyPair オブジェクトを生成
			var privateKeyReader = new PemReader(privateKeyPem);
			var keyPair = (AsymmetricCipherKeyPair)privateKeyReader.ReadObject();

			// RSA暗号オブジェクトを初期化(第1引数 false は「復号」を示す)
			rsa.Init (false, keyPair.Private);

			// 暗号化されたバイト列を渡し、復号されたバイト列を受け取る
			byte[] decrypted = rsa.ProcessBlock(encrypted, 0, encrypted.Length);

			// "hogehoge" と表示されたら復号成功
			Debug.Log ("decrypted: " + Encoding.UTF8.GetString(decrypted));
		}	
	}
}

上記実装にあたっては、BouncyCastle自身のテストコードが参考になった

参考リンク

12
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
12