1.我用golang PKCS11 library branch v3生成了一个ed25519密钥对(它连接到SoftHSM 2):
publicKeyTemplate := []*pkcs11.Attribute{
pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PUBLIC_KEY),
pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),
pkcs11.NewAttribute(pkcs11.CKA_PRIVATE, false),
pkcs11.NewAttribute(pkcs11.CKA_LABEL, "go_ed_3"),
pkcs11.NewAttribute(pkcs11.CKA_TRUSTED, false),
pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_EC_EDWARDS),
pkcs11.NewAttribute(pkcs11.CKA_ID, 1234),
pkcs11.NewAttribute(pkcs11.CKA_ENCRYPT, false),
pkcs11.NewAttribute(pkcs11.CKA_WRAP, false),
pkcs11.NewAttribute(pkcs11.CKA_VERIFY, false),
pkcs11.NewAttribute(pkcs11.CKA_VERIFY_RECOVER, false),
pkcs11.NewAttribute(pkcs11.CKA_DERIVE, false),
pkcs11.NewAttribute(pkcs11.CKA_MODIFIABLE, true),
pkcs11.NewAttribute(pkcs11.CKA_COPYABLE, true),
pkcs11.NewAttribute(pkcs11.CKA_DESTROYABLE, true),
pkcs11.NewAttribute(pkcs11.CKA_EC_PARAMS, []byte{0x13, 0x0c, 0x65, 0x64, 0x77, 0x61, 0x72, 0x64, 0x73, 0x32, 0x35, 0x35, 0x31, 0x39}),
}
// Set private key template
privateKeyTemplate := []*pkcs11.Attribute{
pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PRIVATE_KEY),
pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),
pkcs11.NewAttribute(pkcs11.CKA_PRIVATE, true),
pkcs11.NewAttribute(pkcs11.CKA_LABEL, "go_ed_3"),
pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_EC_EDWARDS),
pkcs11.NewAttribute(pkcs11.CKA_ID, 1234),
}
mechanism := []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_EC_EDWARDS_KEY_PAIR_GEN, nil)}
pub, pri, err := p.GenerateKeyPair(session, mechanism, publicKeyTemplate, privateKeyTemplate)
if err != nil {
fmt.Println("Key generation failed:", err)
return
}
spew.Dump(pub)
spew.Dump(pri)
字符串
1.使用pkcs11-tools,我检查了密钥对是否成功生成,公钥如下:
p11cat pubk/go_ed_2
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEA9JJpbH0+hBryC0zcSdeFwa57up4l4/umPTcZzowSI4Q=
-----END PUBLIC KEY-----
型
1.所以现在我想用我的代码导出公钥。我找到了公钥对象:
ktemplate := []*pkcs11.Attribute{
pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PUBLIC_KEY),
pkcs11.NewAttribute(pkcs11.CKA_ID, 1234),
pkcs11.NewAttribute(pkcs11.CKA_LABEL, "go_ed_2"),
}
if err := p.FindObjectsInit(session, ktemplate); err != nil {
panic(err)
}
objs, _, err := p.FindObjects(session, 1)
if err != nil {
panic(err)
}
if err = p.FindObjectsFinal(session); err != nil {
panic(err)
}
fmt.Println("Objects found:", objs[0])
attr, err := p.GetAttributeValue(session, objs[0], []*pkcs11.Attribute{
pkcs11.NewAttribute(pkcs11.CKA_EC_PARAMS, nil),
pkcs11.NewAttribute(pkcs11.CKA_EC_POINT, nil),
})
if err != nil {
panic(err)
}
fmt.Println("attr:", attr[0].Value)
型
主要的问题是我如何才能从中导出正确的ed25519公钥?
我做了大量的研究,但我还没有找到答案。我知道RSA公钥导出工作如下:
pr, err := p.GetAttributeValue(session, pbk, []*pkcs11.Attribute{
pkcs11.NewAttribute(pkcs11.CKA_MODULUS, nil),
pkcs11.NewAttribute(pkcs11.CKA_PUBLIC_EXPONENT, nil),
})
if err != nil {
panic(err)
}
modulus := new(big.Int)
modulus.SetBytes(pr[0].Value)
bigExponent := new(big.Int)
bigExponent.SetBytes(pr[1].Value)
exponent := int(bigExponent.Uint64())
rsaPub := &rsa.PublicKey{
N: modulus,
E: exponent,
}
pubkeyPem := string(pem.EncodeToMemory(&pem.Block{Type: "RSA PUBLIC KEY", Bytes: x509.MarshalPKCS1PublicKey(rsaPub)}))
log.Printf(" Public Key: \n%s\n", pubkeyPem)
型
对于椭圆密钥,应该使用类似的exportECDSAPublicKey,但ed25519不是这种情况
func exportECDSAPublicKey(session *pkcs11Session, pubHandle pkcs11.ObjectHandle) (crypto.PublicKey, error) {
var err error
var attributes []*pkcs11.Attribute
var pub ecdsa.PublicKey
template := []*pkcs11.Attribute{
pkcs11.NewAttribute(pkcs11.CKA_ECDSA_PARAMS, nil),
pkcs11.NewAttribute(pkcs11.CKA_EC_POINT, nil),
}
if attributes, err = session.ctx.GetAttributeValue(session.handle, pubHandle, template); err != nil {
return nil, err
}
if pub.Curve, err = unmarshalEcParams(attributes[0].Value); err != nil {
return nil, err
}
if pub.X, pub.Y, err = unmarshalEcPoint(attributes[1].Value, pub.Curve); err != nil {
return nil, err
}
return &pub, nil
}
型
1条答案
按热度按时间ou6hu8tu1#
既然已经过了这么久,也许只是为了完成这个问题。
它实际上是
字符串
只不过你得去掉前两个字节
型
如果你可以导出私钥(种子),你可以验证。
型