Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filed to construct sequence from byte [] , while generating PublicKey from public key byte array generated at Go-lang #1272

Closed
hivenet-mdevarasetty-osi opened this issue Oct 31, 2022 · 4 comments

Comments

@hivenet-mdevarasetty-osi
Copy link

hivenet-mdevarasetty-osi commented Oct 31, 2022

I am trying to generate PublicKey object at Java using bouncycastle provider from publickey byte [] generated at Go-lang using https://github.com/kudelskisecurity/crystals-go with Dilithium algorithm.

Within Go-lang able to verify the signature using publickey but when when trying to verify signature at Java using publickey that generated by Go-lang, need to get PublicKey object from byte [] where i am getting failed to construct sequence from byte[] and some times with extra data attached, more than 31 bit...

pubKey = keyFactory.generatePublic(pubKeySpec); failing at this line.

Reference code at java:

public static PublicKey convertByteKeyToPublicKey(byte[] publickey) {
		X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(publickey, "DILITHIUM");
		KeyFactory keyFactory = null;
		PublicKey pubKey = null;
		try {
			keyFactory = KeyFactory.getInstance("DILITHIUM");
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		if (keyFactory != null) {
			try {
				pubKey = keyFactory.generatePublic(pubKeySpec);
				System.out.println(pubKey);
			} catch (InvalidKeySpecException e) {
				e.printStackTrace();
			}
		}
		return pubKey;
	}

(@cipherboy edited for clarity)

@dghgit
Copy link
Contributor

dghgit commented Nov 1, 2022

If you attach a self signed certificate I might be able to help. There's no standards around these algorithms at the moment even for development, a few of us are trying to do something about this, but unfortunately it's not surprising you are having issues.

@hivenet-mdevarasetty-osi
Copy link
Author

hivenet-mdevarasetty-osi commented Nov 10, 2022

@dghgit please find the public key generated at Golang.

-----BEGIN PUBLIC KEY-----
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
ZbAdhT4o8t4=
-----END PUBLIC KEY-----

(@cipherboy edited for clarity)

@hivenet-mdevarasetty-osi
Copy link
Author

hivenet-mdevarasetty-osi commented Nov 10, 2022

@dghgit below is the code to generate public, private and signature at Golang and passing keys to java for bouncy castle to retrieve the actual public key object to verify signature.

package main

import (
	"crypto/x509/pkix"
	"encoding/asn1"
	"encoding/base64"
	"encoding/pem"
	"fmt"
	"net/http"
	"os"
	"strings"
	"time"

	"github.com/cloudflare/circl/sign/dilithium/mode3"
)

func main() {

	// Generates a keypair.
	pk, sk, err := mode3.GenerateKey(nil)
	if err != nil {
		panic(err)
	}
	cid := "This"
	mptr := " is a "
	sequence_number := "message."
	var msg = []byte(cid + mptr + sequence_number)
	var signature [mode3.SignatureSize]byte
	mode3.SignTo(sk, msg, signature[:])

	if !mode3.Verify(pk, msg, signature[:]) {
		panic("incorrect signature")
	}

	packedPk, err := MarshalPKIXPublicKey(*pk)
	str := pem.EncodeToMemory(&pem.Block{
		Type:  "PUBLIC KEY",
		Bytes: packedPk,
	})
	fmt.Printf(string(str))
	// fmt.Printf(string(packedPk))

	publickeyfile, err := os.Create("../bcCryptography/public.key")
	if err != nil {
	   fmt.Println(err)
	   os.Exit(1)
	}
	// publickeyfile.Write(publicKeyBytes)
	publickeyfile.Write(str)
	publickeyfile.Close()

	// sending request to platform
	jsonBody := "{\"publicKey\":\"" + base64.StdEncoding.EncodeToString(str) +
		"\",\"signature\":\"" + base64.StdEncoding.EncodeToString(signature[:]) + "\",\"data\":\"" + base64.StdEncoding.EncodeToString(msg) + "\"}"
	bodyReader := strings.NewReader(jsonBody)
	newrequestURL := "http://localhost:8080/v1/api/crypto/verifySig"
	fmt.Println(bodyReader)
	req, err := http.NewRequest(http.MethodPost, newrequestURL, bodyReader)
	if err != nil {
		fmt.Printf("client: could not create request: %s\n", err)
		os.Exit(1)
	}
	req.Header.Set("Content-Type", "application/json")

	client := http.Client{
		Timeout: 30 * time.Second,
	}

	res, err := client.Do(req)
	if err != nil {
		fmt.Printf("client: error making http request: %s\n", err)
		os.Exit(1)
	}
	fmt.Printf("client: got response!\n")
	fmt.Printf("client: status code: %d\n", res.StatusCode)
}

func MarshalPKIXPublicKey(pk mode3.PublicKey) ([]byte, error) {
	data, err := pk.MarshalBinary()
	if err != nil {
		return nil, err
	}

	return asn1.Marshal(struct {
		pkix.AlgorithmIdentifier
		asn1.BitString
	}{
		pkix.AlgorithmIdentifier{
			Algorithm: asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 2, 267, 7, 6, 5}, // Round 2 strength
		},
		asn1.BitString{
			Bytes:     data,
			BitLength: len(data) * 8,
		},
	})
}

(@cipherboy edited for clarity)

@cipherboy
Copy link
Collaborator

cipherboy commented Mar 11, 2024

@hivenet-mdevarasetty-osi I do not know if you have solved this, but in the mean time, the OIDs for Dilithium has changed and Bouncy Castle has updated to newer draft OIDs for ML-DSA. https://github.com/kudelskisecurity/crystals-go has been archived and https://github.com/cloudflare/circl will update when the NIST draft spec is finalized.

The current version of BC (1.77 at the time of writing) implements the pre-release draft spec with OID 1.3.6.1.4.1.2.267.12.6.5, and don't still implement the Round 3 submission with OIDs given above (1.3.6.1.4.1.2.267.7.6.5). OQS has updated OIDs as of relatively recently, so perhaps CGo bindings to there might be worthwhile.

Going ahead and closing this; once NIST publishes final revisions of these specs a lot of incompatibilities can be worked out... :-) Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants