You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言中OpenSSL与liboqs-go的Dilithium2密钥尺寸对齐

OpenSSL与liboqs-go Dilithium2密钥尺寸对齐方案

差异原因

  • OpenSSL生成的密钥是ASN.1/DER编码的完整密钥结构,包含算法OID、版本信息等元数据,所以总尺寸更大(3870字节);
  • liboqs-go直接输出的是Dilithium2算法的原始二进制密钥材料,没有额外封装层,尺寸为标准的2528字节。

两种密钥本质上是同一算法的密钥,只是封装格式不同,只要统一格式就能实现跨库兼容。


方法1:将liboqs-go密钥封装为OpenSSL兼容格式

把liboqs生成的原始密钥套入OpenSSL使用的ASN.1结构中,这样生成的PEM文件就能直接被OpenSSL识别。

Go代码实现

import (
    "encoding/asn1"
    "encoding/pem"
    "log"
    "os"
)

// Dilithium2的官方OID(OpenSSL识别的标识)
var dilithium2OID = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 2, 267, 7, 4, 4}

// 定义OpenSSL私钥的ASN.1结构
type privateKeyInfo struct {
    Version             int
    PrivateKeyAlgorithm []asn1.RawValue
    PrivateKey          []byte
}

// 将liboqs原始私钥封装为OpenSSL兼容的DER格式
func wrapLiboqsPrivKey(rawPrivKey []byte) ([]byte, error) {
    // 构造算法标识符
    algOIDBytes, err := asn1.Marshal(dilithium2OID)
    if err != nil {
        return nil, err
    }
    algID := asn1.RawValue{
        Tag:   asn1.TagSequence,
        Bytes: algOIDBytes,
    }

    pki := privateKeyInfo{
        Version:             0,
        PrivateKeyAlgorithm: []asn1.RawValue{algID},
        PrivateKey:          rawPrivKey,
    }

    return asn1.Marshal(pki)
}

// 修改原liboqs密钥生成代码
func main() {
    signer := oqs.Signature{}
    err := signer.Init("Dilithium2", nil)
    if err != nil {
        log.Fatalf("failed to initialize signer: %v", err)
    }
    defer signer.Clean()

    pubKey, rawPrivKey, err := signer.GenerateKeyPair()
    if err != nil {
        log.Fatalf("failed to generate key pair: %v", err)
    }

    // 封装私钥为OpenSSL兼容格式
    opensslPrivKeyDER, err := wrapLiboqsPrivKey(rawPrivKey)
    if err != nil {
        log.Fatalf("failed to wrap private key: %v", err)
    }

    // 写入PEM文件
    privBlock := &pem.Block{
        Type:  "PRIVATE KEY",
        Bytes: opensslPrivKeyDER,
    }
    err = os.WriteFile("liboqs_openssl_compat_priv.pem", pem.EncodeToMemory(privBlock), 0600)
    if err != nil {
        log.Fatalf("failed to write private key file: %v", err)
    }

    // 公钥同理,封装为OpenSSL格式
    type pkixPublicKey struct {
        Algorithm asn1.ObjectIdentifier
        Key       []byte
    }
    opensslPubKeyDER, err := asn1.Marshal(pkixPublicKey{
        Algorithm: dilithium2OID,
        Key:       pubKey,
    })
    if err != nil {
        log.Fatalf("failed to wrap public key: %v", err)
    }
    pubBlock := &pem.Block{
        Type:  "PUBLIC KEY",
        Bytes: opensslPubKeyDER,
    }
    err = os.WriteFile("liboqs_openssl_compat_pub.pem", pem.EncodeToMemory(pubBlock), 0644)
    if err != nil {
        log.Fatalf("failed to write public key file: %v", err)
    }
}

方法2:提取OpenSSL密钥的原始材料

从OpenSSL生成的PEM文件中剥离ASN.1封装,提取出和liboqs-go一致的原始密钥字节。

命令行提取(私钥)

# 提取原始私钥字节到文件
openssl pkey -in dilithium_private.pem -outform der | openssl asn1parse -inform der -offset 16 -out dilithium_raw_priv.key -noout

Go代码中直接读取原始密钥

// 读取原始私钥用于liboqs操作
rawPrivKey, err := os.ReadFile("dilithium_raw_priv.key")
if err != nil {
    log.Fatalf("failed to read raw private key: %v", err)
}

signer := oqs.Signature{}
err = signer.Init("Dilithium2", rawPrivKey)
if err != nil {
    log.Fatalf("failed to initialize signer with raw key: %v", err)
}
defer signer.Clean()

// 后续签名操作和原流程一致

兼容性验证

不管用哪种方法,都要验证跨库签名/验证是否正常:

  1. OpenSSL签名 → liboqs-go验证
    # OpenSSL生成签名
    openssl dgst -sign dilithium_private.pem -sha256 -out sig.bin data.txt
    
    // liboqs验证签名
    signer := oqs.Signature{}
    _ = signer.Init("Dilithium2", nil)
    defer signer.Clean()
    
    rawPubKey, _ := os.ReadFile("dilithium_raw_pub.key")
    data, _ := os.ReadFile("data.txt")
    sig, _ := os.ReadFile("sig.bin")
    
    if signer.Verify(data, sig, rawPubKey) {
        log.Println("跨库验证通过")
    } else {
        log.Println("跨库验证失败")
    }
    
  2. liboqs-go签名 → OpenSSL验证
    用封装后的liboqs密钥生成签名,直接用OpenSSL命令验证即可:
    openssl dgst -verify liboqs_openssl_compat_pub.pem -sha256 -signature sig.bin data.txt
    

内容的提问来源于stack exchange,提问作者O21

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 22:55:21