Reputation: 4830
I try to develop an automation to register new IoT device with public RSA pem certificate but I have a problem which is I don't know the reason.
The problem is RSA_PEM public pem is generated my automation is rejected by GCP IoT Server with an error. That error is "The key data for the device credential in position 1 is invalid. Make sure the format is correct: Invalid RS256 public key"
When I debug the my code, the pem public certificate looks fine. But I am not sure that.
I am sharing go code that generate private and public certificates in paired.
package cert
import (
"bytes"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"io"
)
type CertificateRSA struct {
Private io.Reader
Public io.Reader
}
func Create() (*CertificateRSA, error) {
bitSize := 2048
key, err := rsa.GenerateKey(rand.Reader, bitSize)
if err != nil {
return nil, err
}
var privateKey = &pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(key),
}
var priBuff bytes.Buffer
err = pem.Encode(&priBuff, privateKey)
if err != nil {
return nil, err
}
// asn1Bytes := x509.MarshalPKCS1PublicKey(&key.PublicKey)
asn1Bytes := x509.MarshalPKCS1PublicKey(&key.PublicKey)
var publicKey = &pem.Block{
Type: "PUBLIC KEY",
Bytes: asn1Bytes,
}
var pubBuff bytes.Buffer
err = pem.Encode(&pubBuff, publicKey)
return &CertificateRSA{
Private: &priBuff,
Public: &pubBuff,
}, err
}
Can you see any problem in my code ?
And this code can generates certificates like as these:
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA0FGWENPInhIfCLDTqCFKFsyrvmzKsEjJtHEL0Tqh0LtHDWG5
Sh7MT7/x/xNAFc00zmgGG+PPaJDP/7gkGJitRAXcJOlKwlowgmVTf+QGwH81pq3o
ZNRd0mEXbF0EuPBRNt/9TzkZPAlPDGruMCiMq9LWsoIflx+u/3UmXgsyMQTs5vSM
z4T5VCELHGCtfZfBrDAP19KzwjFEUTEzX+Llotp0mO6+cRCslVvSK3xd8KIk2cOm
AXEmCavZnwuVsqCVmNZFoQZvFszisMf5cXZRDstKCGsqDgqIGM5dMMrBS92CqZ4u
j6h9zbMG7J9oXsVmVFiQ++hS0TLJdWwMD+uhWQIDAQABAoIBAAbKIfH6dRdxz8Eg
wkVAkIGduhtCwHhuZuSSqqfvGUcMU4yEGt3nkxEmWGTP487SGV6A1XIjQqdN0Pms
rsB+eWc2Ka6qS915wwr88nPAotezTbRZBrICmew5beICRh0g+ASp2D+0xLXIN+NX
uNuo9qzC+mxnAVCTn8iDsPRvuPsP9vJSy5zIzPWURdPBQ3Ny1pbj+odqwDdUw8q7
FfUmGHC7a5oKex3vxDhDL8OPc3KjynFJdm1YqUagLzppDHMZtI2rNAYfWrkrJVB7
zlX3m0hUDDrvHbQBiqGUj2qI2MqgrFlcK0HSryJdCz4tVdYY3qBi/tZrwOAvnSkv
zNFT6AECgYEA9veJpGwUYdRhWyo05xsatDJ+KvBpizi66Iu2Lu+fRQUuwYaC0DSV
BMr1ktbJzbgbu4XDNrJ8GKrqka06vGjaYVhw1C56LU83hHsckTx+K3fpb9wkFamE
gCZG3uAqflLsEPZ6xPHLe1U+SDZfghLrH90JYi7tTULReAVy5zVs8iECgYEA1/Aq
6ls9kPtJWLEU299WdNGYy5Fx1N8oUj5sjYTfPf/27OeBXWg+CKBIhXk534z9pwqq
LUs7NbmqhuocuxFtE7oxdwqXqUR7qYUdpVuRZ8EmVvBuUGxI1MG6MMKxHxSSpTs5
3tTDAd2WlwPX3jbqAj2WOiL2T97cXNjYyKxiuDkCgYBbI0RnKf9njtGSrAOz2XvE
TfHjdK7uUrQfBxfnQER9WwlDH5l8rjrj9uYjFyKHyU5qqFU/BSTokYJY2h2X0/Xr
AJE6rCAoQliRikEjk7hX4DuELTAf0lv0UqvKqdzkm0NEi0EJFtXpoK6IRZB/Vu3v
50kEM58c6PCWIyShEEUxIQKBgQCg63qf0UTNMWaUcMqxm/sq7TNnqMjisTa0K47r
27Qd2Q1juJZATLnF5eSFizSkssYoYJs3S9QhEm7RQdANXEwkImJQaxVgcAeT6f6Q
xu9SGa9/pIcg6cFQw9oEEmK6XbN27O8Qbw+v6Tka6yNIlzXGW60DQCC8nsErc/IB
ge3DiQKBgA3183wzRLj7oZD/KJHW+BY0Y6ljZ8EQQ5anc3RFsQrJ48MdPtRNvC49
Oe0T2lRznVdiPcGY8DKlBMYXQ4jiXZxpWmM8jNkJYPBhx9rq8zBDESo8DKSFd1Jo
lNADlBGDEPYgxG29hnSOrBf5TI1Fkj15RVZOJ79uaefp98ACIgkl
-----END RSA PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MIIBCgKCAQEA0FGWENPInhIfCLDTqCFKFsyrvmzKsEjJtHEL0Tqh0LtHDWG5Sh7M
T7/x/xNAFc00zmgGG+PPaJDP/7gkGJitRAXcJOlKwlowgmVTf+QGwH81pq3oZNRd
0mEXbF0EuPBRNt/9TzkZPAlPDGruMCiMq9LWsoIflx+u/3UmXgsyMQTs5vSMz4T5
VCELHGCtfZfBrDAP19KzwjFEUTEzX+Llotp0mO6+cRCslVvSK3xd8KIk2cOmAXEm
CavZnwuVsqCVmNZFoQZvFszisMf5cXZRDstKCGsqDgqIGM5dMMrBS92CqZ4uj6h9
zbMG7J9oXsVmVFiQ++hS0TLJdWwMD+uhWQIDAQAB
-----END PUBLIC KEY-----
Upvotes: 0
Views: 2458
Reputation: 71
If you get the:
Error: 7 PERMISSION_DENIED: The signature of device credential in position 0 could not be verified against any registry certificate.
error and your system used to work, check the expiration date of the root CA certificate. It will return this error if it's past the date.
Upvotes: 2
Reputation: 99
It was a miss-match between the key format expected and the type of the key, RSA_PEM vs RSA_X509_PEM. Switching that fixed the issue.
Upvotes: 0
Reputation: 4182
I faced the same issue. I could solve this with the following code.
package cloudIotCore
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"os"
)
func create() {
//
// Create key
//
reader := rand.Reader
bitSize := 2048
key, err := rsa.GenerateKey(reader, bitSize)
if err != nil {
panic(err)
}
publicKeyAsc1Bytes, err := x509.MarshalPKIXPublicKey(&(key.PublicKey))
if err != nil {
panic(err)
}
publicPemKey := &pem.Block{
Type: "PUBLIC KEY",
Bytes: publicKeyAsc1Bytes,
}
privatePemKey := &pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(key),
}
//
// Create Device with publicPemKey
//
:
//
// Save pem files
//
publicPemFile, err := os.Create(PATH_TO_PUBLICKEY)
if err != nil {
panic(err)
}
defer publicPemFile.Close()
err = pem.Encode(publicPemFile, publicPemKey)
if err != nil {
panic(err)
}
privatePemFile, err := os.Create(PATH_TO_PRIVATEKEY)
if err != nil {
panic(err)
}
defer privatePemFile.Close()
err = pem.Encode(privatePemFile, privatePemKey)
if err != nil {
panic(err)
}
}
Upvotes: 0
Reputation: 41957
The encoding header and the encoding method don't match. If you want to use
asn1Bytes := x509.MarshalPKCS1PublicKey(&key.PublicKey)
then the pem.Block
Type should be Type: "RSA PUBLIC KEY",
.
If you want the other common public key format, a SubjectPublicKeyInfo ASN.1 structure, then keep the pem.Block
as you have it and instead use
asn1Bytes, err := x509.MarshalPKIXPublicKey(&key.PublicKey)
I don't know what GCP is expecting but it's almost certainly one or the other.
Upvotes: 0