Karakuri.com

Fintechではたらくアプリケーションエンジニアの技術録

C#と.Net Frameworkを使ってPem形式の秘密鍵や公開鍵をXML形式にして暗号化や署名する方法

会社にはRailsエンジニアの方が多いので、技術や仕様がそっちに引っ張られることが多い環境にいます。最近は会社にも馴染んでそうでもなくなってはきましたが。そんな中、通信の暗号化でクライアント側で暗号化するよう要請が。そこで渡されたのがPem形式の鍵。しかし.Net Frameworkはそのままでは使えません。これをXMLにしないと…。でもどうやって?

コンバーターサイトを使って変換する

まず検討したのが、もらった鍵を変換して使う方法。変換して取得したXMLをクライアントで保持すればいいですね。ただ、鍵を得体の知れないサイトに送信するというのは気持ち悪いです。公開鍵ならまだしも、秘密鍵は尚更躊躇しますよねえ。。。
RSA Key Converter - Superdry Developer

コードでPemからXMLを作る

というわけで、コードからXMLを作る需要も結構あるのかなと。しかしPemのフォーマットと.Net Frameworkが要求するXMLのフォーマットを調べる時間的余裕がある人は少ないでしょう。そんなの勉強してたら何のための標準化、規格化なのか分かりません。というわけで、先駆者が作った資産を使わせてもらいます。
RSA Public, Private, and PKCS #8 key parser

ここにOpenSSLKey.csというファイルが公開されています。このファイルをプロジェクトに追加すればPemからXMLを作ることができます。

private string publicPemKey = 
     "-----BEGIN PUBLIC KEY-----" +
     "pedjdjjdjsjajwhdjifvigkfkrjjwhqjdiock/13jfkcig..." +
     "-----END PUBLIC KEY-----";

public string Encrypt(string data)
{
     var decodedPublicKey = opensslKey.DecodeOpenSSLPublicKey(publicPemKey);
     var provider = opensslKey.DecodeX509PublicKey(decodedPublicKey);

     return provider.Encrypt(Encoding.UTF8.GetByte(data), false);
}

XMLを意識することなくRSACryptoServiceProviderを取得することができ、暗号化することができます。ということは復号化もできますね。

Pemの秘密鍵を.Netで署名する

private string privatePemKey = 
     "-----BEGIN PRIVATE KEY-----" +
     "pedjdjjdjsjajwhdjifvigkfkrjjwhqjdiock/13jfkcig..." +
     "-----END PRIVATE KEY-----";

public string Sign(string data)
{
     var decodedPrivateKey = opensslKey.DecodeOpenSSLPrivateKey(privatePemKey);
     var provider = opensslKey.DecodeRSAPrivateKey(decodedPrivateKey);

     return provider.SignData(Encoding.UTF8.GetBytes(data), "SHA256");
}

こっちは動かしてないけど、たぶんこれで秘密鍵で署名もできるのではないかと思います。