I am trying to distribute an application - and need to add a software license to let the user use the application. I need some information to be distributed in the license regarding authorization(this works great using only public/private key)
Pseudo steps
- Generate the public/private key
- Embed the public key in the code
- Create license using encoding
- Distribute the license file
- Application verifies the license using the embedded public key
6. Problem(using certificate to verify the origin of the public key)
Actual steps:
1 . Generate the public/private key
openssl genrsa -out private_key.pem 3072
openssl rsa -in "private_key.pem -pubout -out public_key.pem
2 - 5 And then embed the private key in code, and read a license file like(code from here):
func VerifyAndExtractPayload(publicKey *rsa.PublicKey, str string) (interface{}, error) {
var err error
str = strings.TrimSpace(str)
if !strings.HasPrefix(str, header) || !strings.HasSuffix(str, footer) {
return nil, errors.New("invalid license key")
}
b64 := strings.Replace(str[len(header):len(str)-len(footer)], "\n", "", -1)
var l license
b, err := base64.StdEncoding.DecodeString(b64)
licenseBuffer := bytes.Buffer{}
licenseBuffer.Write(b)
licenseDecoder := gob.NewDecoder(&licenseBuffer)
if err = licenseDecoder.Decode(&l); err != nil {
return nil, err
}
hashed := sha256.Sum256(l.Payload)
if err = rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, hashed[:], l.Signature); err != nil {
return nil, err
}
var payload interface{}
payloadBuffer := bytes.Buffer{}
payloadBuffer.Write(l.Payload)
payloadDecoder := gob.NewDecoder(&payloadBuffer)
if err = payloadDecoder.Decode(&payload); err != nil {
return nil, err
}
return payload, nil
}
Then I realised that maybe I should use certificate pinning, so no one can replace the public key.
Pseudo code:
- Generate a root certificate using private key
- Embed certificate
- Generate license like above
- Read public key from the certificate
- Application verifies the license using the embedded public key
Questions:
- How to verify read the public key from the certificate?
- And is the public key now verified?