Put inline certificate in YAML - yaml

I've a certificate that I need to copy in a YAML property. Something that could look like this:
ca_cert: | -----BEGIN CERTIFICATE-----
MIIDBzCCAe+gAwIBAgIJALOT/fiqj4yhMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNV
BAMMD3d3dy5leGFtcGxlLmNvbTAeFw0xNzA1MDMxNDA2NDVaFw0yNzA1MDExNDA2
NDVaMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBALHEIGNhuQsD1MI3zE5Kts5zN91ggbFjFq0aLWjYuIB6
ttfpS158b9x9oWbdACAqGIHC5i1/iwiJkW8J1UcxtPOOHZy4s9E48KnPzJOd6yAv
pxsBuns78Jx5hgBBt+J2TSwEL+Hi40HhBiog+Omk2pi3juMGkhFJaaSiBQf7gA0E
TXSC5iLK1XPCd6aQpDZwxQpjDNeDk9CR6asqtPJcm9X2skLuNWyIr8dKHpdzoQ5A
/5GhmtLC/WYwZdqi14Gwph+GS7a2eQYzbGwIZWfcPiMytoNGidDC2HurRpGt91PK
PxfXDhDk8taBuboHFDAW7beR/x68pPm+p2mTtVt+cS0CAwEAAaNQME4wHQYDVR0O
BBYEFDpuS3ujMg9wC09nBy/QRQI8PipqMB8GA1UdIwQYMBaAFDpuS3ujMg9wC09n
By/QRQI8PipqMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAFh6UUfa
YL9iLREMGgHTvn4O4nMtsWEEW46/9o4ZcGgVgIL343qD1G0isaTLStKHB5C653N0
40DU/n9Fcver/x5EhKzjp9QcOSNizFDUG88tCOuW3H+EsTHsCwxdVvENzBT1+Z3N
JkT8oHVjEc3LBeQmVZLHiWWA9CSVW9b6qco0OjLwLe92f1EWKjqrHPW+5xM3zC0e
T2h5p4ApY74Pyl892HJrb/dd2DjzYDnXuvcDFZTAr9o5YgcS1jx0Gt9jE1FM7rhk
GF5aek4Bir9K8xwNBTc8R+dvl2OhQYoxIglSApkNI+n0J9/1pfPnpwojBHifqy/p
G9oErrv2EQ642e4=
-----END CERTIFICATE-----
I've tried the YAML validator but unfortunately it doesn't work

A block scalar cannot start at the same line as the indicator |. Also, you need to indent the block scalar:
ca_cert: |
-----BEGIN CERTIFICATE-----
MIIDBzCCAe+gAwIBAgIJALOT/fiqj4yhMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNV
BAMMD3d3dy5leGFtcGxlLmNvbTAeFw0xNzA1MDMxNDA2NDVaFw0yNzA1MDExNDA2
NDVaMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBALHEIGNhuQsD1MI3zE5Kts5zN91ggbFjFq0aLWjYuIB6
ttfpS158b9x9oWbdACAqGIHC5i1/iwiJkW8J1UcxtPOOHZy4s9E48KnPzJOd6yAv
pxsBuns78Jx5hgBBt+J2TSwEL+Hi40HhBiog+Omk2pi3juMGkhFJaaSiBQf7gA0E
TXSC5iLK1XPCd6aQpDZwxQpjDNeDk9CR6asqtPJcm9X2skLuNWyIr8dKHpdzoQ5A
/5GhmtLC/WYwZdqi14Gwph+GS7a2eQYzbGwIZWfcPiMytoNGidDC2HurRpGt91PK
PxfXDhDk8taBuboHFDAW7beR/x68pPm+p2mTtVt+cS0CAwEAAaNQME4wHQYDVR0O
BBYEFDpuS3ujMg9wC09nBy/QRQI8PipqMB8GA1UdIwQYMBaAFDpuS3ujMg9wC09n
By/QRQI8PipqMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAFh6UUfa
YL9iLREMGgHTvn4O4nMtsWEEW46/9o4ZcGgVgIL343qD1G0isaTLStKHB5C653N0
40DU/n9Fcver/x5EhKzjp9QcOSNizFDUG88tCOuW3H+EsTHsCwxdVvENzBT1+Z3N
JkT8oHVjEc3LBeQmVZLHiWWA9CSVW9b6qco0OjLwLe92f1EWKjqrHPW+5xM3zC0e
T2h5p4ApY74Pyl892HJrb/dd2DjzYDnXuvcDFZTAr9o5YgcS1jx0Gt9jE1FM7rhk
GF5aek4Bir9K8xwNBTc8R+dvl2OhQYoxIglSApkNI+n0J9/1pfPnpwojBHifqy/p
G9oErrv2EQ642e4=
-----END CERTIFICATE-----

Related

SSL certificate problem: unable to get local issuer certificate (only when certificate managed by Terraform)

I am trying on an Elasticsearch cluster to set up HTTPS for clients.
It works fine when I generate an SSL certificate from the cluster using certbot via the following command:
certbot certonly --standalone
My Elasticsearch cluster is configured as follows:
# elasticsearch.yml
cluster.initial_master_nodes: 10.132.0.3
cluster.name: elasticsearch
discovery.seed_hosts: 10.132.0.3:9200
network.host: 10.132.0.3
node.name: node-1
xpack.security.http.ssl.certificate: /etc/elasticsearch/ssl/my-subdomain.XXXX.com/fullchain.pem
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.key: /etc/elasticsearch/ssl/my-subdomain.XXXX.com/privkey.pem
xpack.security.http.ssl.verification_mode: certificate
xpack.security.transport.ssl.enabled: true
I thus manage to authenticate in HTTPS on my elasticsearch using my login and password, via the following command:
curl https://my-subdomain.XXXX.com:9200 -u username:password
My problem is that I would now like to do the same operation but by generating the SSL certificate via Terraform using the ACME provider
and more precisely with the resource "acme_certificate".
Here is my Terraform code:
resource "acme_certificate" "elastic" {
account_key_pem = acme_registration.account_registration.account_key_pem
common_name = "${local.subdomain}.${var.domain_name}"
dns_challenge {
provider = "ovh"
config = {
OVH_ENDPOINT = var.ovh_endpoint
OVH_APPLICATION_KEY = var.ovh_application_key
OVH_APPLICATION_SECRET = var.ovh_application_secret
OVH_CONSUMER_KEY = var.ovh_consumer_key
}
}
}
From Terraform resource "acme_certificate" I get the following outputs:
"certificate_pem" which will become my "cert.pem" file (but I am not using it in my Elasticsearch setup)
"issuer_pem"
"private_key_pem" which will become my "privkey.pem" file
I am therefore missing the "fullchain.pem" file that I build by associating the "certificate_pem" and "issuer_pem" as follows (my error may be there):
resource "local_file" "fullchain" {
content = "${acme_certificate.elastic.certificate_pem}${acme_certificate.elastic.issuer_pem}"
filename = "/my/local/path/fullchain.pem"
}
My "fullchain.pem" file looks like this:
-----BEGIN CERTIFICATE-----
MIIFQjCCBCqgAwIBAgISBBxb+NtLDbApYlOYScK3+iXjMA0GCSqGSIb3DQEBCwUA
MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
EwJSMzAeFw0yMTA4MjAxMzAzNDFaFw0yMTExMTgxMzAzNDBaMCkxJzAlBgNVBAMT
HmRhdGEtZWxhc3RpYy11YXQuMzYwbWVkaWNzLmNvbTCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBAMObjLj+EncIyg0NlJn2BM9KYtUhCWSPCK37T7EcPieF
Z1BcoIU0qKzIvwOLScv98GXd3FHf6tJCJ/uS9x+WhxDzR+94d4LShgl+vQ5rZmc6
GrIL7W/+pLUfGi81vMtDVRm/xG5NpKK2LjqJEPyZlQh6ydmYY1usyKNQXBTUOzlp
GWtYUgR9c6CBkr041moohaNpL+URGdA60Ul/UvxaZDzRBlLGnR+CyT4/Wh/4Hj8E
cw2EWqjxpQZ9jZLd/OHPq1+5mosqSVZ6qgVfM0d8l3db1DUlLFmYFrqH+8Gm+8cm
ev9Ho9Tg8mUye4AbFfN3h+zo94kflEZjBN5CmZmTZ1sCAwEAAaOCAlkwggJVMA4G
A1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYD
VR0TAQH/BAIwADAdBgNVHQ4EFgQUuIHdFbQhRupc20jIB/NxFjzKxc0wHwYDVR0j
BBgwFoAUFC6zF7dYVsuuUAlA5h+vnYsUwsYwVQYIKwYBBQUHAQEESTBHMCEGCCsG
AQUFBzABhhVodHRwOi8vcjMuby5sZW5jci5vcmcwIgYIKwYBBQUHMAKGFmh0dHA6
Ly9yMy5pLmxlbmNyLm9yZy8wKQYDVR0RBCIwIIIeZGF0YS1lbGFzdGljLXVhdC4z
NjBtZWRpY3MuY29tMEwGA1UdIARFMEMwCAYGZ4EMAQIBMDcGCysGAQQBgt8TAQEB
MCgwJgYIKwYBBQUHAgEWGmh0dHA6Ly9jcHMubGV0c2VuY3J5cHQub3JnMIIBBAYK
KwYBBAHWeQIEAgSB9QSB8gDwAHYARJRlLrDuzq/EQAfYqP4owNrmgr7YyzG1P9Mz
lrW2gagAAAF7Y9/g0QAABAMARzBFAiEA3lbnbzdKvfS0XXt6xm0tlr/nxzWMK5hN
HUTCTmsIvr8CICHDYguCoKQbu4BJr8b8w6f61QvTMAyVrRCWlik8SYZ2AHYA9lyU
L9F3MCIUVBgIMJRWjuNNExkzv98MLyALzE7xZOMAAAF7Y9/grAAABAMARzBFAiEA
s0PVaOjanRy8ykpzhz6oja9lf1IBuLtOv07DJTWfQOoCIGft0IELso34PTZw8YnW
QkaNgEwijGjHiBe5ZM8UTHJXMA0GCSqGSIb3DQEBCwUAA4IBAQC3oKR21gY7xWc9
wTE8kAB9/ZHdF5/QuHCCR1aFMmmVwomdUs0ekKqc/fW/kPkAA3csePOosm6RjVfr
63MrPnRIDUHykeCTOeMNfvqHp6ePetBW0guaIOIWSbCJiavXSZBvpR8ctOQ/3JrZ
1/f5E/COL2ly6pYjqYg6M8wQEvC6z9qbq0uQ0eKcfbxtsWprvVUZNVasP3UnhNnD
hHaHRC4ZJOHIN+xC4v//x8soOcSY6okG/35XQq9JwH6Aie2RAhYeL9Ld26Fsz+Pk
uITGCclEL5bhLf+EtTN1hHMS4sfYwZ86zbgN6iOQOOTxGkotkF2Ct/jl8+WhGQdL
1vQ+n1Pb
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw
WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
RW5jcnlwdDELMAkGA1UEAxMCUjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQC7AhUozPaglNMPEuyNVZLD+ILxmaZ6QoinXSaqtSu5xUyxr45r+XXIo9cP
R5QUVTVXjJ6oojkZ9YI8QqlObvU7wy7bjcCwXPNZOOftz2nwWgsbvsCUJCWH+jdx
sxPnHKzhm+/b5DtFUkWWqcFTzjTIUu61ru2P3mBw4qVUq7ZtDpelQDRrK9O8Zutm
NHz6a4uPVymZ+DAXXbpyb/uBxa3Shlg9F8fnCbvxK/eG3MHacV3URuPMrSXBiLxg
Z3Vms/EY96Jc5lP/Ooi2R6X/ExjqmAl3P51T+c8B5fWmcBcUr2Ok/5mzk53cU6cG
/kiFHaFpriV1uxPMUgP17VGhi9sVAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC
AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB
Af8CAQAwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYfr52LFMLGMB8GA1UdIwQYMBaA
FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw
AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw
Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB
gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCFyk5HPqP3hUSFvNVneLKYY611TR6W
PTNlclQtgaDqw+34IL9fzLdwALduO/ZelN7kIJ+m74uyA+eitRY8kc607TkC53wl
ikfmZW4/RvTZ8M6UK+5UzhK8jCdLuMGYL6KvzXGRSgi3yLgjewQtCPkIVz6D2QQz
CkcheAmCJ8MqyJu5zlzyZMjAvnnAT45tRAxekrsu94sQ4egdRCnbWSDtY7kh+BIm
lJNXoB1lBMEKIq4QDUOXoRgffuDghje1WrG9ML+Hbisq/yFOGwXD9RiX8F6sw6W4
avAuvDszue5L3sz85K+EC4Y/wFVDNvZo4TYXao6Z0f+lQKc0t8DQYzk1OXVu8rp2
yJMC6alLbBfODALZvYH7n7do1AZls4I9d1P4jnkDrQoxB3UqQ9hVl3LEKQ73xF1O
yK5GhDDX8oVfGKF5u+decIsH4YaTw7mP3GFxJSqv3+0lUFJoi5Lc5da149p90Ids
hCExroL1+7mryIkXPeFM5TgO9r0rvZaBFOvV2z0gp35Z0+L4WPlbuEjN/lxPFin+
HlUjr8gRsI3qfJOQFy/9rKIJR0Y/8Omwt/8oTWgy1mdeHmmjk7j1nYsvC9JSQ6Zv
MldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqX
nLRbwHOoq7hHwg==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTIxMDEyMDE5MTQwM1oXDTI0MDkzMDE4MTQwM1ow
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwggIiMA0GCSqGSIb3DQEB
AQUAA4ICDwAwggIKAoICAQCt6CRz9BQ385ueK1coHIe+3LffOJCMbjzmV6B493XC
ov71am72AE8o295ohmxEk7axY/0UEmu/H9LqMZshftEzPLpI9d1537O4/xLxIZpL
wYqGcWlKZmZsj348cL+tKSIG8+TA5oCu4kuPt5l+lAOf00eXfJlII1PoOK5PCm+D
LtFJV4yAdLbaL9A4jXsDcCEbdfIwPPqPrt3aY6vrFk/CjhFLfs8L6P+1dy70sntK
4EwSJQxwjQMpoOFTJOwT2e4ZvxCzSow/iaNhUd6shweU9GNx7C7ib1uYgeGJXDR5
bHbvO5BieebbpJovJsXQEOEO3tkQjhb7t/eo98flAgeYjzYIlefiN5YNNnWe+w5y
sR2bvAP5SQXYgd0FtCrWQemsAXaVCg/Y39W9Eh81LygXbNKYwagJZHduRze6zqxZ
Xmidf3LWicUGQSk+WT7dJvUkyRGnWqNMQB9GoZm1pzpRboY7nn1ypxIFeFntPlF4
FQsDj43QLwWyPntKHEtzBRL8xurgUBN8Q5N0s8p0544fAQjQMNRbcTa0B7rBMDBc
SLeCO5imfWCKoqMpgsy6vYMEG6KDA0Gh1gXxG8K28Kh8hjtGqEgqiNx2mna/H2ql
PRmP6zjzZN7IKw0KKP/32+IVQtQi0Cdd4Xn+GOdwiK1O5tmLOsbdJ1Fu/7xk9TND
TwIDAQABo4IBRjCCAUIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw
SwYIKwYBBQUHAQEEPzA9MDsGCCsGAQUFBzAChi9odHRwOi8vYXBwcy5pZGVudHJ1
c3QuY29tL3Jvb3RzL2RzdHJvb3RjYXgzLnA3YzAfBgNVHSMEGDAWgBTEp7Gkeyxx
+tvhS5B1/8QVYIWJEDBUBgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEEAYLfEwEB
ATAwMC4GCCsGAQUFBwIBFiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2VuY3J5cHQu
b3JnMDwGA1UdHwQ1MDMwMaAvoC2GK2h0dHA6Ly9jcmwuaWRlbnRydXN0LmNvbS9E
U1RST09UQ0FYM0NSTC5jcmwwHQYDVR0OBBYEFHm0WeZ7tuXkAXOACIjIGlj26Ztu
MA0GCSqGSIb3DQEBCwUAA4IBAQAKcwBslm7/DlLQrt2M51oGrS+o44+/yQoDFVDC
5WxCu2+b9LRPwkSICHXM6webFGJueN7sJ7o5XPWioW5WlHAQU7G75K/QosMrAdSW
9MUgNTP52GE24HGNtLi1qoJFlcDyqSMo59ahy2cI2qBDLKobkx/J3vWraV0T9VuG
WCLKTVXkcGdtwlfFRjlBz4pYg1htmf5X6DYO8A4jqv2Il9DjXA6USbW1FzXSLr9O
he8Y4IWS6wY7bCkjCWDcRQJMEhg76fsO3txE+FiYruq9RUWhiF1myv4Q6W+CyBFC
Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5
-----END CERTIFICATE-----
In the same way as with cerbot, I inject my certificate into Elasticsearch with Terraform and verify that the Elastic user has the correct rights (with the chmod and chown commands)
The elasticsearch service restarts fine, but when I try to connect it gives me the following error:
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html
I don't understand what the problem is, I have the impression that the certificate returned by Terraform is not correct. But when I test their validity with cerbot, everything seems OK:
openssl x509 -enddate -noout -in cert.pem # notAfter=Nov 16 13:55:54 2021 GMT
openssl x509 -enddate -noout -in fullchain.pem # notAfter=Nov 16 13:55:54 2021 GMT
Thanks for your help !

Private ssh key content as CLI argument

Following the example in Buildkite charts, I'm looking to specify the contents of my private key using cat:
helm install buildkite --name bk-agent --namespace buildkite \
--set privateSshKey="$(cat buildkite.key)"
The problem I'm having is that $(cat buildkite.key) gives an invalid format where there are no longer newlines. In other words my env variable looks like:
SSH_PRIVATE_RSA_KEY=-----BEGIN RSA PRIVATE KEY----- abcedefw123232= -----END RSA PRIVATE KEY-----
instead of:
SSH_PRIVATE_RSA_KEY=-----BEGIN RSA PRIVATE KEY-----
abcedefw123232=
-----END RSA PRIVATE KEY-----
I'm generating the private key with:
ssh-keygen -t rsa -b 4096 -N '' -C "my_name" -f ./my_key
How can I pass the contents of a private key in the command line?

How to use contents of a file stored in a variable, instead of creating a file with the contents in bash

I am trying to convert a OpenSSL private key to OpenSSH public Key.
I am doing this using the following command.
ssh-keygen -f -y
Now i want this to be done using a variable which contains the contents of "OpenSSL-Private-Key-File", Instead of using the "OpenSSL-Private-Key" itself. How can this be done in bash. I am trying to avoid creation of files. Please help.
You can try this:
read -r -d '' VARIABLEKEY << EOM
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAwbTpqo5OSwvsDdXdQo0jtHOaiHJXw4WxvdzM2EjcoblAQFjx
9mmDAY6RrIjoY6hhg902NqP9zMAr32DLzeZyrPvIAOtP44PJidv3mxWp2g92Zbx9
EB8XZ6EpYhwrXOhM1NlJYiFEPCiawiTQdShrIN/9uHI0eJeql/xN5mjvPUEchojf
Qur4Hb0ocmu6Rffy0yxKo1P3H5z0y6iZV+ovEWxZoFG6/mdO51nyzmAk5V9fD/Bz
/4ef1hxm7WCsjU4mUNOFQAYsTlsQBgFVWLe5WUGLAdGwjSWzzRHOV0Q8LHAuWhdF
YpTUYEt0sgik76lLGK3RzLql2X+cbzfHNC0akQIDAQABAoIBAGNNWGCcFVz5nqi1
E3mzmzM99GGwpHdSiXz4vXa/W4P40QxrzJbzHjrlGJ7njKLSRjNwawN17H1Touof
2DsUwYMWjECUYV8UR3RJ9NRnNazZMmwTRdXG6puwjeOC52P4nrKbNbh9r1pbwoJ2
lvsInmq7CXnN6kJMFiNWL6VH9CVk4GX9A2F86BiRbnCUjrY75kA+iOdjyA6FpaNL
1j47ZfbB4K9zmfx/pyUoV5LYBKejkeWqnxl8jvRaHCbm6MLDYOMsGNvHkimUI1J0
zYJ53zSByRABl7fFlLCGuGD19dr5Hjn1Jl19AeqwlDplAa8zYhennoA4U81PqRmu
gTvqZgECgYEA3sRjUHCV04MvaUkLYJkNZiNM1EylE8DFu5tqhjzT2/Hm0wvJd+uH
EeoihMG0R83lL9mXyfKR2ETTHoILxi4+qDYIt07ZC54WIYw/xEFraiir3N0gMhPR
RNUblGQHaPj501N7dTGZdqv41sOt83qqt8olrMhKQN+NgGSHzT3mqSECgYEA3pqw
SZeyU+sqmUirrTwnohre6ZpReXoPhjtg/9XCDn+pMLYC3C8Mfw+s58AYn7PBlbYI
prpECdZEZRHA71mQzVKhM1TFPaJ/hThDe777hwRCxAGEA5SHrDE6g90rFH63B8HB
AK+gZgzgG7e97J9j3LrstWWs+o3q1lGRsj3vE3ECgYAE56gUJlZ2MMZDeDNC7jvI
SvCvH/zmgXEZH2PqDr7PcfUWIoVOGaaAs3oNGELC7fqk4hKghLHHZESNwGlH9M62
X3Izrw3CXrm4BWGGDbaywLCADXJfB+assFCKJOWw3wKJL6ZhPzVU0paJDAfxe3r0
zwOjWUmhQgrYj94Zm8pPYQKBgAmjvTqSnSBRMLkOkpCf6D921mxbSGfwRzfS3nJ1
uT+Te6omV51dVDc0YJJwmSBhUmK/TUSbEFM0uiV+TVKQGFsr1ts4MopmvQrx0spL
DO1d295NCoB1MCLext/q9fCfRCHL3CXBdTq2GAZbQJg8lsB6P8HjM0huWNsLEToc
wHuhAoGAMo+zHUNsoVGJLgFBJtvtPXlvfd4OQyi4MDZlfPYxeDkDTIJQ0wqOId0v
qTURBYmmCP2BAIzM8EJqOre5wKWnZPS1ktcwFOt8m7wCb8OpDPztLXsyE6CJ0mX4
EjUxLdvqijyUTMG7mAC4IxNY8V6izzgCN2ipw5sdv0ZPWtrTepw=
-----END RSA PRIVATE KEY-----
EOM
echo "$VARIABLEKEY" | ssh-keygen -y -f /dev/stdin

how to convert raw modulus & exponent to RSA public key (.pem format)

I have the modulus & exponent of an RSA public key embedded into a binary file, and I am trying to extract the entire blob and create a usable .pem public key.
Currently, I am extracting the full 260 bytes (4 bytes for the exponent, 256 bytes for the modulus)
and encoding as base64. I am doing that using the following shell command :
tail -c $((filesize - start_of_key_data)) filename | head -c $size_of_key_data | base64 > outkey
This gives me the following string :
<<<<<< modulus & exponent extracted from binary file, base64-encoded >>>>>>
tZyrQA6cZFJfVm6FyXwtZaLQYg8EecuO+ObrHTwc8JO+XrgnpNAdmlhbAEPxSNnjwhNnbYGYGL4F
vzmnZXzZU71Key42HQPh1k2Zx1UDbrH5ciODKx1ZbuEx8K24SHnL1nY/H75hwhT/ZRRVGQDvYDT+
sgzw2vmV66+dflw1Zs8BLhqjLjczdHvjeVXsDRJ9Mvvd/dhFH8UlTf4JpLGya9nsNIfNBBIf1Lll
RWwCTiEIbaOMgWcLjLV/2tk/j5Dra/oQnVf/2hVsEF/hXEx41YjeEW/warweoDVG7zaxrHEc/k/r
ZCUCZKxf8nBKdqax/gRICvkG6e5xg2GQw0W/ZwABAAE=
Now, when I take the key.pem keypair that the modulus & exponent were originally extracted from, and display the public portion like so
openssl rsa -in key.pem -pubout -out pubkey.pem
I get this string (I have omitted the header & footer lines :
<<<<<<<<< valid public key data extracted from keypair >>>>>>>>>
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtZyrQA6cZFJfVm6FyXwt
ZaLQYg8EecuO+ObrHTwc8JO+XrgnpNAdmlhbAEPxSNnjwhNnbYGYGL4FvzmnZXzZ
U71Key42HQPh1k2Zx1UDbrH5ciODKx1ZbuEx8K24SHnL1nY/H75hwhT/ZRRVGQDv
YDT+sgzw2vmV66+dflw1Zs8BLhqjLjczdHvjeVXsDRJ9Mvvd/dhFH8UlTf4JpLGy
a9nsNIfNBBIf1LllRWwCTiEIbaOMgWcLjLV/2tk/j5Dra/oQnVf/2hVsEF/hXEx4
1YjeEW/warweoDVG7zaxrHEc/k/rZCUCZKxf8nBKdqax/gRICvkG6e5xg2GQw0W/
ZwIDAQAB
You can see that the key data which I have extracted and base64-encoded myself is
actually present in the data of the valid public key data extracted from the key.pem using openssl.
However there are 45 characters at the beginning, that my own extracted data does not have -
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
and the last 8 characters also differ.
ZwIDAQAB
Can anybody offer some advice on how to convert a modulus and exponent into a usable public key?
(the goal is to do this in a bash script, not python or C as I've seen many suggest.)
Command which you used, openssl rsa -in key.pem -pubout -out pubkey.pem, produces the ASN.1 structure like this:
SEQUENCE(2 elem)
SEQUENCE(2 elem)
OBJECT IDENTIFIER 1.2.840.113549.1.1.1
NULL
BIT STRING(1 elem)
SEQUENCE(2 elem)
INTEGER(2048 bit) 229263895356027367204242482830890190076375310244080661230946245232688…
INTEGER 65537
(You can see the structure with openssl asn1parse -in pubkey.pem, or using an online ASN.1 decoder).
It contents:
a fixed header (contains all bytes, specifying the encoding of the
whole sequence plus the encoding of the modulus)
modulus
header, specifying encoding of the exponent
exponent
If you have the modulus and exponent bytes correctly collected, you can construct the the public key in form, understandable by OpenSSL, by concatenating these four things. You already have the first longer header. The "middle header" is '02 03':
'02' for the integer
length of the integer itself is 3 bytes (65537 = 01 00 01)
If your modulus is 2048 bits (256 bytes) and exponent 3 bytes (so that the length fields remain valid), the PEM file can be produced by concatenating these four:
<header> <modulus> 0x02 0x03 <exponent>
That is why the last bytes from the binary dump differ from the OpenSSL output: the extracted 260 bytes do not contain 02 03, but instead record 65537 as 00 01 00 01 (not 01 00 01 as in ASN.1 encoding).
To summarize, you can produce the PEM file like this:
Convert your extracted modulus+exponent back from base64 and extract them (note the 257 byte offset to skip the leading zero byte of 65537!):
echo 'tZyrQA6cZFJfVm6FyXwtZaLQYg8EecuO+ObrHTwc8JO+XrgnpNAdmlhbAEPxSNnjwhNnbYGYGL4FvzmnZXzZU71Key42HQPh1k2Zx1UDbrH5ciODKx1ZbuEx8K24SHnL1nY/H75hwhT/ZRRVGQDvYDT+sgzw2vmV66+dflw1Zs8BLhqjLjczdHvjeVXsDRJ9Mvvd/dhFH8UlTf4JpLGya9nsNIfNBBIf1LllRWwCTiEIbaOMgWcLjLV/2tk/j5Dra/oQnVf/2hVsEF/hXEx41YjeEW/warweoDVG7zaxrHEc/k/rZCUCZKxf8nBKdqax/gRICvkG6e5xg2GQw0W/ZwABAAE=' | base64 -d > modulus-exp.bin
dd if=modulus-exp.bin of=modulus.bin bs=1 count=256
dd if=modulus-exp.bin of=exponent.bin bs=1 skip=257 count=3
Create the headers:
echo 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA' | base64 -d > header.bin
echo '02 03' | xxd -r -p > mid-header.bin
Concatenate them together:
cat header.bin modulus.bin mid-header.bin exponent.bin > key.der
Convert to PEM:
openssl pkey -inform der -outform pem -pubin -in key.der -out key.pem
Test that you get the working key - by checking it with ASN.1 decoder, or by
openssl asn1parse -in key.pem
openssl asn1parse -in key.pem -strparse 19
you can use python3
from Crypto.PublicKey import RSA
e = int('your exponent', 16)
n = int('your modules', 16)
# Construct a `RSAobj` with only ( n, e ), thus with only PublicKey
RSA.construct( ( n, e ) ).publickey().exportKey()
reference I have a RSA public key exponent and modulus. How can I encrypt a string using Python?

Invalid public keys when using the Ruby OpenSSL library

I'm trying to generate RSA keypairs in Ruby, mostly using the examples from this blog post. Here is my slightly modified code:
def generate_keypair(passphrase)
rsa_key = OpenSSL::PKey::RSA.new(2048)
cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
private_key = rsa_key.to_pem(cipher, passphrase)
public_key = rsa_key.public_key.to_pem
return private_key, public_key
end
This successfully generates a private key and a public key, and I can write those out to files on the filesystem.
irb(main):002:0> private_key1, public_key1 = generate_keypair('test')
[...output of keys...]
irb(main):003:0> File.open("key.pem","w") {|f| f.write(private_key1) }
=> 1766
irb(main):004:0> File.open("pubkey.pem","w") {|f| f.write(public_key1) }
=> 426
However, OpenSSL complains when I try to use this public key:
$ openssl rsautl -encrypt -inkey pubkey.pem -pubin -in text.txt -out text.ssl
unable to load Public Key
If I use the openssl tool to extract the public key from the private key then everything works:
$ openssl rsa -in key.pem -pubout -out pubkey2.pem
Enter pass phrase for key.pem:
writing RSA key
$ openssl rsautl -encrypt -inkey pubkey2.pem -pubin -in text.txt -out text.ssl
$ openssl rsautl -decrypt -inkey key.pem -in text.ssl
Enter pass phrase for key.pem:
this is a
file that
needs to be
encrypted
The public key that the Ruby OpenSSL library produced is different from the public key that the openssl cli tool extracted from the private key:
$ cat pubkey.pem
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAzgNcsEL7yGBoLBYBXFYrDL6oLP8ZbW9+VwdoXyNG6Qt/NEhEx4Ww
5yOxtXAbqeUwyvbTUxRrJ02dQcb4FGcSMDgz2QHIZyCuDJkgC9Wj7KI1Q7g0GV+7
DcZvLcwPZOhLXqUzlcZXjDWM1PZ+az734qEribgyI+87LB8TujG8v5iOvdzT/Je4
JAllToZVGC3RddfTc6ww37gB39B++FYNzPg+nrIEU45KgEWPo2eJxBpX29lACh6q
EEBCQr9xyLxOC2eomYIl3dG2dV7nGGH7Pur2HjppgJphBvNkwxIWUa/pD6hAnOQ4
MkDDFGwWv7eJLb4UZuZjafTbqokHved3bwIDAQAB
-----END RSA PUBLIC KEY-----
$ cat pubkey2.pem
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzgNcsEL7yGBoLBYBXFYr
DL6oLP8ZbW9+VwdoXyNG6Qt/NEhEx4Ww5yOxtXAbqeUwyvbTUxRrJ02dQcb4FGcS
MDgz2QHIZyCuDJkgC9Wj7KI1Q7g0GV+7DcZvLcwPZOhLXqUzlcZXjDWM1PZ+az73
4qEribgyI+87LB8TujG8v5iOvdzT/Je4JAllToZVGC3RddfTc6ww37gB39B++FYN
zPg+nrIEU45KgEWPo2eJxBpX29lACh6qEEBCQr9xyLxOC2eomYIl3dG2dV7nGGH7
Pur2HjppgJphBvNkwxIWUa/pD6hAnOQ4MkDDFGwWv7eJLb4UZuZjafTbqokHved3
bwIDAQAB
-----END PUBLIC KEY-----
I'm not quite sure what is going on here, but it seems as if the Ruby OpenSSL library is producing an invalid public key pem file. Am I doing something wrong?
It seems that OSSL doesn't support that format. What "openssl rsa" generates is an RSA_PUBKEY structure: a PUBKEY record which is ASN.1-"tagged" (with an OID) to indicate that it's an RSA key. What Ruby generates is a "raw" RSA key (where the bytes don't indicate that it is RSA; so you have to declare that in the PEM header).
OSSL should use an API function like PEM_write_bio_RSA_PUBKEY (or the generic PEM_write_bio_PUBKEY), instead of/in addition to PEM_write_bio_RSAPublicKey.

Resources