I'm using JCSL - Javascript on client (documentation) and OpenSSL - Ruby on server (documentation) to generate a symmetric key on both client and server using Elliptic Curve Diffie-Hellman.
I've somehow finally managed to format properly the public keys to be sent by the Client and Server, and I've finally generated a symmetric key without anymore runtime errors (my previous question)
However, the problem now is that Client's Symmetric Key != Server's Symmetric Key
I feel that it would be best if you could try this out on your computer, so I thought of uploading the compiled JS file from JCSL (this includes the Elliptic Curve) for testing convenience (link)
My Code as follows (you can just copy-paste this for testing convenience):
#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
While on Client Side,
//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>
Thus my problem is
f8de0a7012765a1ff8b7630c917a1d3d2ac9cc0d782fbb6c0c101128a29232fec5194468b7ed846053abab05744c61e9
!=
0xa779359617b008884b67c0785a3f782b9dca6e46f9586f7e911b73de877f2aca
Feel free to ask me how to convert format and stuff if you want to test or anything, as this is vital for my project. Please help. Thanks