繁体   English   中英

客户端和服务器上不匹配的椭圆曲线Diffie-Hellman对称密钥

[英]Elliptic Curve Diffie-Hellman Symmetric Keys Not Matching On Client and Server

我正在使用JCSL-客户端上的Javascript (文档)和OpenSSL-服务器上的Ruby (文档),以使用Elliptic Curve Diffie-Hellman在客户端和服务器上生成对称密钥。

我终于以某种方式设法正确格式化要由客户端和服务器发送的公钥,并且最终生成了一个对称密钥,不再出现运行时错误(我之前的问题)

但是,现在的问题是Client's Symmetric Key != Server's Symmetric Key

我认为最好在计算机上进行尝试,因此我考虑从JCSL(包括椭圆曲线)上载已编译的JS文件,以进行测试(链接)

我的代码如下(为了方便测试,您可以复制粘贴此代码):

#Ruby on Rails
class EcdhController < ApplicationController

  @@group = OpenSSL::PKey::EC::Group.new('secp384r1')
  @@ec = OpenSSL::PKey::EC.new(@@group)

  def connect
    logger.info('CONNECT PAGE:::::::::::::::::')
  end

  def send_params
    logger.info('SEND_PARAMS::::::::::::::::::')

    #GENERATE PUBLIC AND PRIVATE KEYS
    @@ec.generate_key

    #SEND PUBLIC KEY TO CLIENT/BROWSER
    #[2..-1] means I've removed the first two Hex characters which is x04 which I think is automatically prepended by OpenSSL which causes errors in the Client JS side
    render :json => {:server_pub_key => @@ec.public_key.to_bn.to_s(16)[2..-1]}
  end

  def receive_client_pub_key
    logger.info('RECEIVE_CLIENT_PUB_KEY:::::::::::::::')

    #Convert properly the format of the JCSL pub key on client side
    client_pub_key = (params[:client_pub_key].split(",").map { |s| s.to_i }).pack('N*')

    #Copied from https://stackoverflow.com/questions/11135420/elliptic-curve-cryptography-with-sjcl-in-js-and-openssl-in-ruby
    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#{client_pub_key}"
    root = OpenSSL::ASN1::Sequence.new [algo,key]

    pub = OpenSSL::PKey.read(root.to_der)
    #-End of copied code-#

    #COMPUTE SYMMETRIC KEY
    symm_key = @@ec.dh_compute_key(pub.public_key)

    puts "SYMM KEY: #{symm_key.unpack('H*').first}"

    #---> SYMM KEY: f8de0a7012765a1ff8b7630c917a1d3d2ac9cc0d782fbb6c0c101128a29232fec5194468b7ed846053abab05744c61e9    

    render :json => nil
  end
end

在客户端时,

//Javascript
<h1>Ecdh#connect</h1>
<p>Find me in app/views/ecdh/connect.html.erb</p>

<script>
    $(document).ready(function ()
    {
        var server_pub_key;
        var client_priv_key;
        var client_pub_key;

        connect();

        function connect()
        {
            //Receive Server Public Key
            jQuery.getJSON('<%= url_for(:controller => :ecdh, :action => :send_params) %>', function(data)
            {
                //Get Server Public Key
                server_pub_key_Bits = new sjcl.bn(data.server_pub_key.toString()).toBits(); //Convert Hex String to BN, and then to Bits

                //Client Keys
                client_keys = sjcl.ecc.elGamal.generateKeys(384, 0);
                client_keys.generate_keys;

                client_pub_key_Hex = sjcl.bn.fromBits( client_keys.pub.serialize().point ).toString(16); //Into bits, then to Hex
                client_priv_key = client_keys.sec; //sjcl.ecc.elGamal.privateKey format

                //Send Client/Own Public Key to Server
                jQuery.getJSON('<%= url_for(:controller => :ecdh, :action => :receive_client_pub_key) %>?client_pub_key='+client_keys.pub.serialize().point, function()
                {
                    //Set Curve from Template
                    curve = sjcl.ecc.curves['c384'];

                    //Convert server_pub_key_Bits to proper 'publicKey' format
                    server_pub_key = new sjcl.ecc.elGamal.publicKey(384, curve, server_pub_key_Bits);

                    //Compute Shared Key
                    symm_key_Bits = client_priv_key.dh(server_pub_key);
                    symm_key_Hex = sjcl.bn.fromBits(symm_key_Bits).toString(16);

                    console.log(symm_key_Hex);

                    //---> 0xa779359617b008884b67c0785a3f782b9dca6e46f9586f7e911b73de877f2aca
                }); 
            }); 
        }
    }); 
</script>

因此我的问题是

f8de0a7012765a1ff8b7630c917a1d3d2ac9cc0d782fbb6c0c101128a29232fec5194468b7ed846053abab05744c61e9
!=
0xa779359617b008884b67c0785a3f782b9dca6e46f9586f7e911b73de877f2aca

随意问我,如果要测试或进行任何其他操作,如何转换格式和内容,这对我的项目至关重要。 请帮忙。 谢谢

我终于解决了这个问题:)

我现在在Javascript客户端上使用JSBN-EC (链接)而不是JCSL。

请参考(本)我的另一个问题,了解更多详情

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM