7

サーバー側でECCを使用してデータを暗号化し、ブラウザーで復号化できる必要があるWebアプリケーションに取り組んでいます。私が見つけたJSでこれが可能な唯一のライブラリはSJCLです。ただし、SJCLでのECCサポートは現時点では少し放棄されているように思われるため、キーのシリアル化をサポートし、理解しやすいようにデモを備えたフォークを使用しました。

まず、JSでECCキーペアを生成します。

keypair = sjcl.ecc.elGamal.generateKeys(384, 10);
document.writeln(JSON.stringify(keypair.pub.serialize()));

これは次のようなものを出力します:

{"point":[1110230655,241884220,775655552,-849225963,-883815628,-1984298210,-736346431,1387519594,-1810604283,-1235638489,1333314084,-1219216530,614640565,-1148742381,1038670260,1013716131,758346573,1162278003,1232401864,-1948620456,533899535,-1478577959,1853846180,-1553049184],"curve":384}

次に、この公開鍵をOpenSSLで理解できる形式に変換しようとしました。

ar = [1110230655,241884220,775655552,-849225963,-883815628,-1984298210,-736346431,1387519594,-1810604283,-1235638489,1333314084,-1219216530,614640565,-1148742381,1038670260,1013716131,758346573,1162278003,1232401864,-1948620456,533899535,-1478577959,1853846180,-1553049184]

# ugly bit magic to somehow convert the above array into a proper byte array (in form of a string)
kstr = [(ar.map { |i| (i>=0)?('0'*(8-i.to_s(16).length)+i.to_s(16)):("%08X" % (2**32-1+i+1)) }*'').upcase].pack("H*")

# opening a public key generated with the openssl cli tool showed a structure like this:
algokey = OpenSSL::ASN1::ObjectId 'id-ecPublicKey'
algovalue = OpenSSL::ASN1::ObjectId 'secp384r1'
algo = OpenSSL::ASN1::Sequence.new [algokey,algovalue]
# for some reason OpenSSL seems to prepend 0x04 to all public keys
key = OpenSSL::ASN1::BitString.new "\x04#{kstr}"
root = OpenSSL::ASN1::Sequence.new [algo,key]

pub = OpenSSL::PKey.read(root.to_der)

この時点まで、私のコードは正常に機能します。つまり、例外は発生しません。

ただし、両方のライブラリで共有シークレットを生成すると、SJCLが96バイトの長さの「タグ」を生成し、OpenSSLが48バイトを生成することがわかりました。

私の問題は、SJCLがプレーンECDHを使用していないことです。それはクイックグーグル検索に基づいてECMQVのように見えるものを使用しています。したがって、「タグ」SJCL出力は曲線上のポイント(ポイントのxおよびy座標、2 * 48バイト)であり、OpenSSL出力は共有シークレット(ECDHで指定されたポイントのx座標)でした。

私の問題は、OpenSSLでECMQVがサポートされているかどうかわからないことです(私が正しければ、いくつかの特許の問題があります)。あったとしても、ルビーバインディングはそれをサポートしていないようです。

だから私の実際の質問:

  • 上記で文書化された私の調査結果は正しいですか?
  • はいの場合、ECMQVをサポートするOpenSSLの代わりに使用できる他のrubyライブラリを誰かが知っていますか?
4

1 に答える 1

2

JavaScriptコードでElGamalを使用しているようです。私は実際にrubyの実装を見つけることができませんでした。代わりに、Crypto ++またはlibgcryptを使用して、グルーコードを記述しています。

追伸:その行の代わりにkstr =、あなたは単に書くことができますkstr = ar.pack 'N*'

于 2012-06-24T16:42:24.460 に答える