简体   繁体   English

如何在golang中通过CGO绑定openssl c绑定

[英]How to bind openssl c binding via CGO in golang

Situation:情况:

  • Need to use EdDSA 448 JSON web encryption in GoLang, ref需要在 GoLang 中使用EdDSA 448 JSON web 加密, 参考
  • Couldn't find JWT library which supports this in GoLang在 GoLang 中找不到支持此功能的 JWT 库
  • We are using jwcrypto in Python, need similar lib in GO我们在 Python 中使用jwcrypto ,在 GO 中需要类似的库
# Example header
{
  "alg": "ECDH-ES",
  "enc": "A256CBC-HS512",
  "epk": {
    "crv": "X448",
    "kty": "OKP",
    "x": "PNJPrNo7grr4y9m9CaxetWdMWA91aAkBf9xM2bsaJHzcLx5RZWyaBfOMhaGDioPEnOT6alPJ0sE"
  }
}

Task:任务:

  • Decrypt and verify payload in GO解密并验证 GO 中的有效载荷

Actions:行动:

  • Used josekit-rs in Rust which can solve this在 Rust 中使用josekit-rs可以解决这个问题
  • Created C API via safer_ffi通过safer_ffi创建C API
  • Bind the library via CGO in Golang在 Golang 中通过 CGO 绑定库

Result:结果:

  • Whole binding thing works when used simple function (without openssl)使用简单的 function(不带 openssl)时,整个绑定的东西都有效
$ go build . 
# go-jose-kit/jose-kit-ffi
Undefined symbols for architecture arm64:
  "_AES_ige_encrypt", referenced from:
      openssl::aes::aes_ige::h356a909c3f173638 in libjose_kit_ffi.a(openssl-83ba33f9169f6e94.openssl.2a7d90ad-cgu.15.rcgu.o)
  "_AES_set_decrypt_key", referenced from:
      openssl::aes::AesKey::new_decrypt::h6be3702416d4e43e in libjose_kit_ffi.a(openssl-83ba33f9169f6e94.openssl.2a7d90ad-cgu.15.rcgu.o)
  "_AES_set_encrypt_key", referenced from:
      openssl::aes::AesKey::new_encrypt::heb205e6bc2f989db in libjose_kit_ffi.a(openssl-83ba33f9169f6e94.openssl.2a7d90ad-cgu.15.rcgu.o)
  "_AES_unwrap_key", referenced from:
. . .
. . .
enssl-83ba33f9169f6e94.openssl.2a7d90ad-cgu.13.rcgu.o)
  "_i2d_X509_REQ", referenced from:
      openssl::x509::X509ReqRef::to_der::h5e65612242296419 in libjose_kit_ffi.a(openssl-83ba33f9169f6e94.openssl.2a7d90ad-cgu.13.rcgu.o)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

It seems CGO is unable to find external methods (symbols) used by rust binary.似乎 CGO 无法找到 rust 二进制文件使用的外部方法(符号)。

Tried to create static lib but it isn't possible to link openssl within rust compiled object.尝试创建 static 库,但无法在 rust 编译的 ZA8CFDE6311BD59EB2AC96.B89 内链接openssl

In main.go file have added these headers.在 main.go 文件中添加了这些头文件。

#cgo CFLAGS: -I/opt/homebrew/opt/openssl@3/include
#cgo LDFLAGS: -L/opt/homebrew/opt/openssl@3/lib -L ./target/debug -l jose_kit_ffi -l pthread -l dl -lm
#include "./jose_kit_ffi.h"
$ go env
GO111MODULE=""
GOARCH="arm64"
GOBIN=""
GOCACHE="/Users/{USERNAME}/Library/Caches/go-build"
GOENV="/Users/{USERNAME}/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="arm64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/{USERNAME}/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/{USERNAME}/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/opt/homebrew/Cellar/go/1.18.1/libexec"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/opt/homebrew/Cellar/go/1.18.1/libexec/pkg/tool/darwin_arm64"
GOVCS=""
GOVERSION="go1.18.1"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/{PATH}/go.mod"
GOWORK=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/8l/_xp4ll7n4c3dqjxrs8klhkqh0000gn/T/go-build3058634703=/tmp/go-build -gno-record-gcc-switches -fno-common"

Solved it via creating dylib instead of static lib.通过创建 dylib 而不是 static lib 解决了这个问题。

[package]
name = "jose-kit-ffi"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[lib]
# crate-type = ["staticlib"] -> Doesn't work
crate-type = ["dylib"] -> 
# ^ It won't include openssl symbols in binary.

[dependencies]
safer-ffi = { version = "0.0.10", features = ["proc_macros"] }
josekit = "0.8.1"
serde_json = "1.0"


[features]
c-headers = ["safer-ffi/headers"]

Result结果

go run .
2022/08/21 22:19:14 Hello, from GO!
JwkSecret { priv_key: "--", pub_key: "--" }
Encrypted JWT: eyJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwiZXBrIjp7Imt0eSI6Ik9LUCIsImNydiI6Ilg0NDgiLCJ4IjoiTmdjRlE4bFY3WWtjUWMtNXR6RlhuUnZvcEI0NlZVTnhPWHFKajgwSzNLQnR4YWh1al9zM3ZNRVY4WVA0cnVvNkttS0FNR0FCN1M4In0sImFsZyI6IkVDREgtRVMifQ..q9BgTEh2UPjiSgLNfu0BTw.rLDyrLQYwtWpi4Qyo43csmERW-VNXowQQBPmqu7zj7U.epX8cMdNA9o9xzMTVdaxJALdtgruVyox5JaPYxKpwZ8
Some("eyJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwiZXBrIjp7Imt0eSI6Ik9LUCIsImNydiI6Ilg0NDgiLCJ4IjoiTmdjRlE4bFY3WWtjUWMtNXR6RlhuUnZvcEI0NlZVTnhPWHFKajgwSzNLQnR4YWh1al9zM3ZNRVY4WVA0cnVvNkttS0FNR0FCN1M4In0sImFsZyI6IkVDREgtRVMifQ..q9BgTEh2UPjiSgLNfu0BTw.rLDyrLQYwtWpi4Qyo43csmERW-VNXowQQBPmqu7zj7U.epX8cMdNA9o9xzMTVdaxJALdtgruVyox5JaPYxKpwZ8")

Hei, I suggest u using github.com/golang-jwt/jwt/v4 lib.嘿,我建议你使用 github.com/golang-jwt/jwt/v4 lib。 this popular i think.我认为这很受欢迎。 And Recommended as the one in https://jwt.io or if u need more, u can see another recommendation library JWT in there.并推荐为https://jwt.io中的一个,或者如果您需要更多,您可以在其中查看另一个推荐库 JWT。

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

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