最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

node.js - ECDH Exchange in Go, NodeJS, and Lua - Stack Overflow

programmeradmin5浏览0评论

Go and NodeJS produced the same result, but not Lua. I want Lua to produce the same one.

package main

import (
    "crypto/ecdh"
    "encoding/base64"
    "log"
    "os"

    "github/joho/godotenv"
)

func main() {
    _ = godotenv.Load()

    aDecodedPrivateKey, _ := base64.StdEncoding.DecodeString(os.Getenv("A_PRIVATE_KEY"))
    bDecodedPrivateKey, _ := base64.StdEncoding.DecodeString(os.Getenv("B_PRIVATE_KEY"))

    aPrivateKey, _ := ecdh.P256().NewPrivateKey(aDecodedPrivateKey)
    bPrivateKey, _ := ecdh.P256().NewPrivateKey(bDecodedPrivateKey)

    sharedSecret, _ := aPrivateKey.ECDH(bPrivateKey.PublicKey())

    log.Println(base64.StdEncoding.EncodeToString(sharedSecret))
}
require('dotenv').config()

import { createECDH } from 'crypto'

const aKey = createECDH('prime256v1')
const bKey = createECDH('prime256v1')

aKey.setPrivateKey(Buffer.from(String(process.env.A_PRIVATE_KEY), 'base64'))
bKey.setPrivateKey(Buffer.from(String(process.env.B_PRIVATE_KEY), 'base64'))

console.log(aKeyputeSecret(bKey.getPublicKey()).toString('base64'))
local openssl_pkey = require "resty.openssl.pkey"
local openssl_bn = require "resty.openssl.bn"
local ngx = require "ngx"

local function ecdh()
  local a_decoded_key = ngx.decode_base64(a_private_key)
  local b_decoded_key = ngx.decode_base64(b_private_key)
  local a_bn = openssl_bn.new(a_decoded_key, 2)
  local b_bn = openssl_bn.new(b_decoded_key, 2)

  local a_key = openssl_pkey.new({
    type = "EC",
    params = {
      private = a_bn,
      group = "prime256v1"
    }
  })
  local b_key = openssl_pkey.new({
    type = "EC",
    params = {
      private = b_bn,
      group = "prime256v1"
    }
  })
  local b_public_key = openssl_pkey.new(b_key:to_PEM('public'))

  return ngx.encode_base64(a_key:derive(b_public_key))
end

Please help me create the Lua version that produces the same result as Go and NodeJS.

In case you need environment variables, take this .env.

A_PRIVATE_KEY="w2UwuwmF9h5p02fnr3MkxtKoDTl8aTtJXqLbsPwbqPg="
B_PRIVATE_KEY="ZyoPMal0TZzNwDyUUE30iThXCKgPOthPaIN2qnOhkNs="

Here is my testing environment.

  • Go 1.23.4
  • NodeJS v22.12.0
  • Lua 5.1

References that might help.

  • #restyopensslpkey
  • .lua

Thank you in advance.

Go and NodeJS produced the same result, but not Lua. I want Lua to produce the same one.

package main

import (
    "crypto/ecdh"
    "encoding/base64"
    "log"
    "os"

    "github.com/joho/godotenv"
)

func main() {
    _ = godotenv.Load()

    aDecodedPrivateKey, _ := base64.StdEncoding.DecodeString(os.Getenv("A_PRIVATE_KEY"))
    bDecodedPrivateKey, _ := base64.StdEncoding.DecodeString(os.Getenv("B_PRIVATE_KEY"))

    aPrivateKey, _ := ecdh.P256().NewPrivateKey(aDecodedPrivateKey)
    bPrivateKey, _ := ecdh.P256().NewPrivateKey(bDecodedPrivateKey)

    sharedSecret, _ := aPrivateKey.ECDH(bPrivateKey.PublicKey())

    log.Println(base64.StdEncoding.EncodeToString(sharedSecret))
}
require('dotenv').config()

import { createECDH } from 'crypto'

const aKey = createECDH('prime256v1')
const bKey = createECDH('prime256v1')

aKey.setPrivateKey(Buffer.from(String(process.env.A_PRIVATE_KEY), 'base64'))
bKey.setPrivateKey(Buffer.from(String(process.env.B_PRIVATE_KEY), 'base64'))

console.log(aKey.computeSecret(bKey.getPublicKey()).toString('base64'))
local openssl_pkey = require "resty.openssl.pkey"
local openssl_bn = require "resty.openssl.bn"
local ngx = require "ngx"

local function ecdh()
  local a_decoded_key = ngx.decode_base64(a_private_key)
  local b_decoded_key = ngx.decode_base64(b_private_key)
  local a_bn = openssl_bn.new(a_decoded_key, 2)
  local b_bn = openssl_bn.new(b_decoded_key, 2)

  local a_key = openssl_pkey.new({
    type = "EC",
    params = {
      private = a_bn,
      group = "prime256v1"
    }
  })
  local b_key = openssl_pkey.new({
    type = "EC",
    params = {
      private = b_bn,
      group = "prime256v1"
    }
  })
  local b_public_key = openssl_pkey.new(b_key:to_PEM('public'))

  return ngx.encode_base64(a_key:derive(b_public_key))
end

Please help me create the Lua version that produces the same result as Go and NodeJS.

In case you need environment variables, take this .env.

A_PRIVATE_KEY="w2UwuwmF9h5p02fnr3MkxtKoDTl8aTtJXqLbsPwbqPg="
B_PRIVATE_KEY="ZyoPMal0TZzNwDyUUE30iThXCKgPOthPaIN2qnOhkNs="

Here is my testing environment.

  • Go 1.23.4
  • NodeJS v22.12.0
  • Lua 5.1

References that might help.

  • https://github.com/fffonion/lua-resty-openssl?tab=readme-ov-file#restyopensslpkey
  • https://github.com/fffonion/lua-resty-openssl/blob/master/examples/x25519-dh.lua

Thank you in advance.

Share Improve this question edited 2 days ago user29212913 asked 2 days ago user29212913user29212913 271 silver badge2 bronze badges New contributor user29212913 is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
Add a comment  | 

1 Answer 1

Reset to default 1

I see at least three problems:

  1. X25519 and prime256v1 are totally different curves. You need to pick one or the other and use it consistently.
  2. That's not the right syntax to make a pkey with existing key material. Here's how you'd modify that part of your code to do that correctly:
local openssl_bn = require "resty.openssl.bn"
local a_bn = openssl_bn.new(a_decoded_key, 2)
local a_key = openssl_pkey.new({
  type = "EC",
  params = {
    private = a_bn,
    group = "prime256v1"
  }
})
  1. OpenSSL doesn't automatically calculate the public key from the private key, so you have to do that yourself, as How do I obtain the public key from an ECDSA private key in OpenSSL? explains. Unfortunately, lua-resty-openssl doesn't expose a lot of necessary functions for this, e.g., EC_POINT_mul, so you'd have to either switch libraries or write a lot of C FFI code yourself to do this.
发布评论

评论列表(0)

  1. 暂无评论