emmansun / gmsm

ShangMi (SM) cipher suites for golang (Go语言商用密码软件)

Home Page:https://emmansun.github.io/gmsm

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

SM9 SignMasterPublicKey Unmarshaling Error

pedroalbanese opened this issue · comments

Greetings!

I started implementing the SM9 curve in EdgeTk, but I'm facing a problem that seems simple, but I can't solve it.

I'm using masterKey.Public().MarshalASN1() to convert public keys to PEM, but I can't do the reverse process. I managed to implement ECDH, signature and asymmetric encryption, but the difficulty concerns the storage and transport of public keys.

This example demonstrates the error I'm getting:

package main

import (
	"crypto/rand"
	"encoding/pem"
	"fmt"
	"github.com/emmansun/gmsm/sm9"
	"github.com/emmansun/gmsm/smx509"
)

func main() {
	// Generate SM9 master key with a non-nil rand.Reader
	masterKey, err := sm9.GenerateSignMasterKey(rand.Reader)
	if err != nil {
		fmt.Println("Error generating SM9 master key:", err)
		return
	}

	// Convert master key to PEM format
	masterKeyBytes, err := smx509.MarshalPKCS8PrivateKey(masterKey)
	if err != nil {
		fmt.Println("Error marshaling master key:", err)
		return
	}

	masterKeyPEM := pem.EncodeToMemory(&pem.Block{
		Type:  "SM9 SIGN MASTER KEY",
		Bytes: masterKeyBytes,
	})

	// Generate SM9 user key from master key
	userKey, err := masterKey.GenerateUserKey([]byte("emmansun"), 0x01)
	if err != nil {
		fmt.Println("Error generating SM9 user key:", err)
		return
	}

	// Convert private key to PEM format
	privKeyBytes, err := smx509.MarshalPKCS8PrivateKey(userKey)
	if err != nil {
		fmt.Println("Error marshaling private key:", err)
		return
	}

	privKeyPEM := pem.EncodeToMemory(&pem.Block{
		Type:  "SM9 SIGN PRIVATE KEY",
		Bytes: privKeyBytes,
	})

	// Export public key
	pubKeyBytes := userKey.MasterPublicKey.Marshal()
	pubKeyPEM := pem.EncodeToMemory(&pem.Block{
		Type:  "SM9 SIGN PUBLIC KEY",
		Bytes: pubKeyBytes,
	})

	fmt.Println("SM9 Master Key (PEM):")
	fmt.Println(string(masterKeyPEM))

	fmt.Println("SM9 Private Key (PEM):")
	fmt.Println(string(privKeyPEM))

	fmt.Println("SM9 Public Key (PEM):")
	fmt.Print(string(pubKeyPEM))

	// Test UnmarshalASN1 function
	testUnmarshalASN1(pubKeyBytes)
}

// Function to test UnmarshalASN1
func testUnmarshalASN1(pubKeyBytes []byte) {
	// Test UnmarshalASN1 for public key
	pubKey := new(sm9.SignMasterPublicKey)
	err := pubKey.UnmarshalASN1(pubKeyBytes)
	if err != nil {
		fmt.Println("Error parsing public key with UnmarshalASN1:", err)
		return
	}

	fmt.Println("UnmarshalASN1 for SM9 keys succeeded.")
}

If it's possible to point out where I'm going wrong, that would be great, as I don't understand what's wrong. Tips are welcome.

Thanks in advance.

Sorry, it was my mistake! Now I get it..

Thank you for this genius library!!

Tell me @emmansun,

I was reading about IBE and the information is that if a private key is lost or misplaced, it does not compromise the master key.

But assuming a misplaced key is capable of decrypting messages encrypted with the master public key for the misplaced key ID, won't the master public key also be compromised?

What is the revocation scheme for lost/misplaced keys?

Thanks in advance.

I was reading about IBE and the information is that if a private key is lost or misplaced, it does not compromise the master key.

Do you mean the user private key is lost o misplaced? if yes, I do not think it will compromise the master key.

But assuming a misplaced key is capable of decrypting messages encrypted with the master public key for the misplaced key ID, won't the master public key also be compromised?

As the name, the master public key is public.

What is the revocation scheme for lost/misplaced keys?

I think this is the mechanism of KGC. I'm not sure if GM/T 0086-2020 基于SM9标识密码算法的密钥管理系统技术规范 provided mechanisms for key revocation and key renewal. This is a difficult problem for IBC.

To be more specific, suppose a user's private key has been misplaced. Whoever is in possession of the misplaced key will be able to decrypt messages directed to the uid of the lost key, that is, even generating a new user private key, the lost key contains the ability to decrypt any message encrypted by the master public key. That is, either the uid or the public master key would need to be renewed to prevent anyone who possesses the lost key from being able to decrypt messages encrypted by the public master key.

In the GM/T 0086-2020 documentation, there is a section on key cancellation (8.6), but it is in Chinese and I don't understand how that happens..

My question may seem meaningless, but it is pure curiosity. I mean, if the uid is unique for each generated user key, there is no need for revocation, this would imply that the uid has more structure, like addition of a salt, but I have nowhere to confirm these assumptions.. Thank you anyway.

I also do NOT know the real use cases, but according GM/T 0086-2020, there are still central organization PKG/KGC similar like CA.
image

Other users/clients can query the UID status from PPS regularly, if the target user's UID status is revoked, then the sender can remove it from his contact list.

For the "lost key" and historical messages encrypted with the old UID, just like asymmetric key pair, and current PKI:
If it's stolen, it's stolen.

Thank You!