Pro Tip: Convert Certs to Strings

Pro Tip: Convert Certs to Strings

I spend a lot of time staring at YAML. Despite it's occasional annoyances, it has become a ubiquitous configuration language used by many IaC tools... and further cemented in DevOps history thanks to Kubernetes' choice of YAML over TOML or other options.

Aside from spending hours finding extra (or missing) spaces, one common task I encounter while configuring products with YAML is converting multi-line TLS certs to one-line strings. The nice thing about UNIX is there's always more than one way to solve problems like this, but I found the following one-liner useful without requiring too many moving parts.

First, let's generate a dummy cert for testing:

❯ openssl genrsa -out testCA.key 2048
Generating RSA private key, 2048 bit long modulus
....................................................................+++
...............................................+++
e is 65537 (0x10001)

~
❯ cat testCA.key
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEA0wITL4x8RB2keE8PwTP6LvtHTOf6W7qi/hFbIGUDy+UFPUjU
3ArhqdBuR6RHhvqK6omzmsEhoe7NKzpXfNsgvdsAdvbgrzcPnV0ScLU4UP/U76pF
l8YJ3PKoli7XGHjqNyw+kQgceMSoAFaPDgi41k/Iv3YUG+gRqLTCalkzrAzaWv+p
nnCHK0yZrNOr54E6JdS9XJe4aF0XH00Xo/mfV9Appvz6JNa7CE02hT0sB/RLi+nr
kwyZCDdf3ElL1fUGzpLH2mp1u4s0Qiw2J+G2AjYFCZ4ahOu/RtZJEVNiDBjnuqIR
2L/P4j8xWy+l6Gnh0r5yb4e39ZOgCriVHmwDeQIDAQABAoIBAG+VnFG7yAc5ab1Z
iepQs0/e//CSiFmz0/fpc7go0x4i6WdkOXR3qKhlmbv3CwA9Q/MNiNYgpcl9gDAI
9TUIqELeKlu+6EigJHjCPDswCi0DbTakY5MEXjjidfadpI/DeZBdrGSD1pKi5Hjx
TUtNn3ltzao6Jh4v1g7SMDGPJH0phQS6lUyEymtrhJcmoAOVlKs/fY/tpQ92J6il
q0JMGcm3NvitD9snuvz6sbjb1ndHSVHzyvzezxT4Ycf++u+Mi/Znh0FcftTjftdY
dYo49Mzhb4/MB02DlBi0MuFDglhD2CXp6OitBIw8M2xJP4hIYfq2dzcIzemcuFC4
dBWIlXUCgYEA64QGRjJN1G2fPFjF2Tf8E8cKwbLR2DZKdS1gtdF/PgpaAq/9FVDG
yB0WZtCNvaN7uClbYK8bVpUFgW3l9ITO03BcEvONBij3+yDl97KBgOCdhHdSb2a9
mxLaCh5C2fM2i8uehZC2O95dLOtHH1eiBhNLosnrWOBh1yz1vi/+4Z8CgYEA5Vxd
njKKfSRDiRySMsjjkmbTE9RL6DWYOiQ7SYrckCo96ZFOlmrOI9QACLKCa/vJ80bs
I7kjXR4VBLLi7n8EVDeIj5ewZdlOtrgqy8K0CAeGwZRyuJZRaIU1ADQhhDiKx5a+
HzZ61h/BMYd5Zt9vRJ+HAb8+EO2+tUnOxT9sc+cCgYAqHR6eGMqwDLYnrVwbnpY1
1ybGQjqh5ftkfqvHd2HAb0tvJZck45/YEtN5qRtfaMdrxAFyBX3m+pjUbxlqowD0
8CeWv/RcwKCvSE+2/jWIHSItmMSl5QJMo49XtdeQb5w2XT/IdHsRs46HxL6gDSSM
35Br2J179Auq1YBP9Pcn0wKBgCSHr4lwt0nzKqZ93HMmN8irg9bWqzhSwOoRtzeh
XDvB3paCxCeE30wpic/YzpjwQ1vx4c5WwGEmV2amLyqZJFFdfuyP1lKCZ90GPBqz
6gSVXksan6LyngitnqFnrCbo8oGTariB7tKHwDdpQla2I3ykg9YtZW9Azm0FUl9s
GJPlAoGAVE9+xei52k7Gv2dtaoEzZXONHviA0C+eO9VIOEKmlafDBxKij2pKNmxC
ARJxdY5PQQNbtSJIZ1S/GLyzhce8Vr9vdF9AM+mSQOQlEFECJ80NR8sSJJ7Judo5
j5a4n+8J+cSLLXn85PBskE2T23h+WHQqm0pG5qAlqwYBdGxZcmY=
-----END RSA PRIVATE KEY-----

Some use cases require certs get fed in as a string vs multi-line value...  Let's convert that cert to a string with all our \n's carefully preserved, using only a single command:

❯ awk '{printf "%s\\n", $0}' testCA.key
-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEA0wITL4x8RB2keE8PwTP6LvtHTOf6W7qi/hFbIGUDy+UFPUjU\n3ArhqdBuR6RHhvqK6omzmsEhoe7NKzpXfNsgvdsAdvbgrzcPnV0ScLU4UP/U76pF\nl8YJ3PKoli7XGHjqNyw+kQgceMSoAFaPDgi41k/Iv3YUG+gRqLTCalkzrAzaWv+p\nnnCHK0yZrNOr54E6JdS9XJe4aF0XH00Xo/mfV9Appvz6JNa7CE02hT0sB/RLi+nr\nkwyZCDdf3ElL1fUGzpLH2mp1u4s0Qiw2J+G2AjYFCZ4ahOu/RtZJEVNiDBjnuqIR\n2L/P4j8xWy+l6Gnh0r5yb4e39ZOgCriVHmwDeQIDAQABAoIBAG+VnFG7yAc5ab1Z\niepQs0/e//CSiFmz0/fpc7go0x4i6WdkOXR3qKhlmbv3CwA9Q/MNiNYgpcl9gDAI\n9TUIqELeKlu+6EigJHjCPDswCi0DbTakY5MEXjjidfadpI/DeZBdrGSD1pKi5Hjx\nTUtNn3ltzao6Jh4v1g7SMDGPJH0phQS6lUyEymtrhJcmoAOVlKs/fY/tpQ92J6il\nq0JMGcm3NvitD9snuvz6sbjb1ndHSVHzyvzezxT4Ycf++u+Mi/Znh0FcftTjftdY\ndYo49Mzhb4/MB02DlBi0MuFDglhD2CXp6OitBIw8M2xJP4hIYfq2dzcIzemcuFC4\ndBWIlXUCgYEA64QGRjJN1G2fPFjF2Tf8E8cKwbLR2DZKdS1gtdF/PgpaAq/9FVDG\nyB0WZtCNvaN7uClbYK8bVpUFgW3l9ITO03BcEvONBij3+yDl97KBgOCdhHdSb2a9\nmxLaCh5C2fM2i8uehZC2O95dLOtHH1eiBhNLosnrWOBh1yz1vi/+4Z8CgYEA5Vxd\nnjKKfSRDiRySMsjjkmbTE9RL6DWYOiQ7SYrckCo96ZFOlmrOI9QACLKCa/vJ80bs\nI7kjXR4VBLLi7n8EVDeIj5ewZdlOtrgqy8K0CAeGwZRyuJZRaIU1ADQhhDiKx5a+\nHzZ61h/BMYd5Zt9vRJ+HAb8+EO2+tUnOxT9sc+cCgYAqHR6eGMqwDLYnrVwbnpY1\n1ybGQjqh5ftkfqvHd2HAb0tvJZck45/YEtN5qRtfaMdrxAFyBX3m+pjUbxlqowD0\n8CeWv/RcwKCvSE+2/jWIHSItmMSl5QJMo49XtdeQb5w2XT/IdHsRs46HxL6gDSSM\n35Br2J179Auq1YBP9Pcn0wKBgCSHr4lwt0nzKqZ93HMmN8irg9bWqzhSwOoRtzeh\nXDvB3paCxCeE30wpic/YzpjwQ1vx4c5WwGEmV2amLyqZJFFdfuyP1lKCZ90GPBqz\n6gSVXksan6LyngitnqFnrCbo8oGTariB7tKHwDdpQla2I3ykg9YtZW9Azm0FUl9s\nGJPlAoGAVE9+xei52k7Gv2dtaoEzZXONHviA0C+eO9VIOEKmlafDBxKij2pKNmxC\nARJxdY5PQQNbtSJIZ1S/GLyzhce8Vr9vdF9AM+mSQOQlEFECJ80NR8sSJJ7Judo5\nj5a4n+8J+cSLLXn85PBskE2T23h+WHQqm0pG5qAlqwYBdGxZcmY=\n-----END RSA PRIVATE KEY-----\n

Some times you can just use the cert as a multi-line value, or perhaps you got the string version from an API and want to convert back to multi-line. For that, we just need echo:

❯ echo "$(awk '{printf "%s\\n", $0}' testCA.key)"
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEA0wITL4x8RB2keE8PwTP6LvtHTOf6W7qi/hFbIGUDy+UFPUjU
3ArhqdBuR6RHhvqK6omzmsEhoe7NKzpXfNsgvdsAdvbgrzcPnV0ScLU4UP/U76pF
l8YJ3PKoli7XGHjqNyw+kQgceMSoAFaPDgi41k/Iv3YUG+gRqLTCalkzrAzaWv+p
nnCHK0yZrNOr54E6JdS9XJe4aF0XH00Xo/mfV9Appvz6JNa7CE02hT0sB/RLi+nr
kwyZCDdf3ElL1fUGzpLH2mp1u4s0Qiw2J+G2AjYFCZ4ahOu/RtZJEVNiDBjnuqIR
2L/P4j8xWy+l6Gnh0r5yb4e39ZOgCriVHmwDeQIDAQABAoIBAG+VnFG7yAc5ab1Z
iepQs0/e//CSiFmz0/fpc7go0x4i6WdkOXR3qKhlmbv3CwA9Q/MNiNYgpcl9gDAI
9TUIqELeKlu+6EigJHjCPDswCi0DbTakY5MEXjjidfadpI/DeZBdrGSD1pKi5Hjx
TUtNn3ltzao6Jh4v1g7SMDGPJH0phQS6lUyEymtrhJcmoAOVlKs/fY/tpQ92J6il
q0JMGcm3NvitD9snuvz6sbjb1ndHSVHzyvzezxT4Ycf++u+Mi/Znh0FcftTjftdY
dYo49Mzhb4/MB02DlBi0MuFDglhD2CXp6OitBIw8M2xJP4hIYfq2dzcIzemcuFC4
dBWIlXUCgYEA64QGRjJN1G2fPFjF2Tf8E8cKwbLR2DZKdS1gtdF/PgpaAq/9FVDG
yB0WZtCNvaN7uClbYK8bVpUFgW3l9ITO03BcEvONBij3+yDl97KBgOCdhHdSb2a9
mxLaCh5C2fM2i8uehZC2O95dLOtHH1eiBhNLosnrWOBh1yz1vi/+4Z8CgYEA5Vxd
njKKfSRDiRySMsjjkmbTE9RL6DWYOiQ7SYrckCo96ZFOlmrOI9QACLKCa/vJ80bs
I7kjXR4VBLLi7n8EVDeIj5ewZdlOtrgqy8K0CAeGwZRyuJZRaIU1ADQhhDiKx5a+
HzZ61h/BMYd5Zt9vRJ+HAb8+EO2+tUnOxT9sc+cCgYAqHR6eGMqwDLYnrVwbnpY1
1ybGQjqh5ftkfqvHd2HAb0tvJZck45/YEtN5qRtfaMdrxAFyBX3m+pjUbxlqowD0
8CeWv/RcwKCvSE+2/jWIHSItmMSl5QJMo49XtdeQb5w2XT/IdHsRs46HxL6gDSSM
35Br2J179Auq1YBP9Pcn0wKBgCSHr4lwt0nzKqZ93HMmN8irg9bWqzhSwOoRtzeh
XDvB3paCxCeE30wpic/YzpjwQ1vx4c5WwGEmV2amLyqZJFFdfuyP1lKCZ90GPBqz
6gSVXksan6LyngitnqFnrCbo8oGTariB7tKHwDdpQla2I3ykg9YtZW9Azm0FUl9s
GJPlAoGAVE9+xei52k7Gv2dtaoEzZXONHviA0C+eO9VIOEKmlafDBxKij2pKNmxC
ARJxdY5PQQNbtSJIZ1S/GLyzhce8Vr9vdF9AM+mSQOQlEFECJ80NR8sSJJ7Judo5
j5a4n+8J+cSLLXn85PBskE2T23h+WHQqm0pG5qAlqwYBdGxZcmY=
-----END RSA PRIVATE KEY-----

In this case we just wrapped our command, but you could also use a file as the input. The key is simply wrapping the input in double quotes:

❯ cat test-string.crt
-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEA0wITL4x8RB2keE8PwTP6LvtHTOf6W7qi/hFbIGUDy+UFPUjU\n3ArhqdBuR6RHhvqK6omzmsEhoe7NKzpXfNsgvdsAdvbgrzcPnV0ScLU4UP/U76pF\nl8YJ3PKoli7XGHjqNyw+kQgceMSoAFaPDgi41k/Iv3YUG+gRqLTCalkzrAzaWv+p\nnnCHK0yZrNOr54E6JdS9XJe4aF0XH00Xo/mfV9Appvz6JNa7CE02hT0sB/RLi+nr\nkwyZCDdf3ElL1fUGzpLH2mp1u4s0Qiw2J+G2AjYFCZ4ahOu/RtZJEVNiDBjnuqIR\n2L/P4j8xWy+l6Gnh0r5yb4e39ZOgCriVHmwDeQIDAQABAoIBAG+VnFG7yAc5ab1Z\niepQs0/e//CSiFmz0/fpc7go0x4i6WdkOXR3qKhlmbv3CwA9Q/MNiNYgpcl9gDAI\n9TUIqELeKlu+6EigJHjCPDswCi0DbTakY5MEXjjidfadpI/DeZBdrGSD1pKi5Hjx\nTUtNn3ltzao6Jh4v1g7SMDGPJH0phQS6lUyEymtrhJcmoAOVlKs/fY/tpQ92J6il\nq0JMGcm3NvitD9snuvz6sbjb1ndHSVHzyvzezxT4Ycf++u+Mi/Znh0FcftTjftdY\ndYo49Mzhb4/MB02DlBi0MuFDglhD2CXp6OitBIw8M2xJP4hIYfq2dzcIzemcuFC4\ndBWIlXUCgYEA64QGRjJN1G2fPFjF2Tf8E8cKwbLR2DZKdS1gtdF/PgpaAq/9FVDG\nyB0WZtCNvaN7uClbYK8bVpUFgW3l9ITO03BcEvONBij3+yDl97KBgOCdhHdSb2a9\nmxLaCh5C2fM2i8uehZC2O95dLOtHH1eiBhNLosnrWOBh1yz1vi/+4Z8CgYEA5Vxd\nnjKKfSRDiRySMsjjkmbTE9RL6DWYOiQ7SYrckCo96ZFOlmrOI9QACLKCa/vJ80bs\nI7kjXR4VBLLi7n8EVDeIj5ewZdlOtrgqy8K0CAeGwZRyuJZRaIU1ADQhhDiKx5a+\nHzZ61h/BMYd5Zt9vRJ+HAb8+EO2+tUnOxT9sc+cCgYAqHR6eGMqwDLYnrVwbnpY1\n1ybGQjqh5ftkfqvHd2HAb0tvJZck45/YEtN5qRtfaMdrxAFyBX3m+pjUbxlqowD0\n8CeWv/RcwKCvSE+2/jWIHSItmMSl5QJMo49XtdeQb5w2XT/IdHsRs46HxL6gDSSM\n35Br2J179Auq1YBP9Pcn0wKBgCSHr4lwt0nzKqZ93HMmN8irg9bWqzhSwOoRtzeh\nXDvB3paCxCeE30wpic/YzpjwQ1vx4c5WwGEmV2amLyqZJFFdfuyP1lKCZ90GPBqz\n6gSVXksan6LyngitnqFnrCbo8oGTariB7tKHwDdpQla2I3ykg9YtZW9Azm0FUl9s\nGJPlAoGAVE9+xei52k7Gv2dtaoEzZXONHviA0C+eO9VIOEKmlafDBxKij2pKNmxC\nARJxdY5PQQNbtSJIZ1S/GLyzhce8Vr9vdF9AM+mSQOQlEFECJ80NR8sSJJ7Judo5\nj5a4n+8J+cSLLXn85PBskE2T23h+WHQqm0pG5qAlqwYBdGxZcmY=\n-----END RSA PRIVATE KEY-----\n

❯ echo "$(cat test-string.crt)"
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEA0wITL4x8RB2keE8PwTP6LvtHTOf6W7qi/hFbIGUDy+UFPUjU
3ArhqdBuR6RHhvqK6omzmsEhoe7NKzpXfNsgvdsAdvbgrzcPnV0ScLU4UP/U76pF
l8YJ3PKoli7XGHjqNyw+kQgceMSoAFaPDgi41k/Iv3YUG+gRqLTCalkzrAzaWv+p
nnCHK0yZrNOr54E6JdS9XJe4aF0XH00Xo/mfV9Appvz6JNa7CE02hT0sB/RLi+nr
kwyZCDdf3ElL1fUGzpLH2mp1u4s0Qiw2J+G2AjYFCZ4ahOu/RtZJEVNiDBjnuqIR
2L/P4j8xWy+l6Gnh0r5yb4e39ZOgCriVHmwDeQIDAQABAoIBAG+VnFG7yAc5ab1Z
iepQs0/e//CSiFmz0/fpc7go0x4i6WdkOXR3qKhlmbv3CwA9Q/MNiNYgpcl9gDAI
9TUIqELeKlu+6EigJHjCPDswCi0DbTakY5MEXjjidfadpI/DeZBdrGSD1pKi5Hjx
TUtNn3ltzao6Jh4v1g7SMDGPJH0phQS6lUyEymtrhJcmoAOVlKs/fY/tpQ92J6il
q0JMGcm3NvitD9snuvz6sbjb1ndHSVHzyvzezxT4Ycf++u+Mi/Znh0FcftTjftdY
dYo49Mzhb4/MB02DlBi0MuFDglhD2CXp6OitBIw8M2xJP4hIYfq2dzcIzemcuFC4
dBWIlXUCgYEA64QGRjJN1G2fPFjF2Tf8E8cKwbLR2DZKdS1gtdF/PgpaAq/9FVDG
yB0WZtCNvaN7uClbYK8bVpUFgW3l9ITO03BcEvONBij3+yDl97KBgOCdhHdSb2a9
mxLaCh5C2fM2i8uehZC2O95dLOtHH1eiBhNLosnrWOBh1yz1vi/+4Z8CgYEA5Vxd
njKKfSRDiRySMsjjkmbTE9RL6DWYOiQ7SYrckCo96ZFOlmrOI9QACLKCa/vJ80bs
I7kjXR4VBLLi7n8EVDeIj5ewZdlOtrgqy8K0CAeGwZRyuJZRaIU1ADQhhDiKx5a+
HzZ61h/BMYd5Zt9vRJ+HAb8+EO2+tUnOxT9sc+cCgYAqHR6eGMqwDLYnrVwbnpY1
1ybGQjqh5ftkfqvHd2HAb0tvJZck45/YEtN5qRtfaMdrxAFyBX3m+pjUbxlqowD0
8CeWv/RcwKCvSE+2/jWIHSItmMSl5QJMo49XtdeQb5w2XT/IdHsRs46HxL6gDSSM
35Br2J179Auq1YBP9Pcn0wKBgCSHr4lwt0nzKqZ93HMmN8irg9bWqzhSwOoRtzeh
XDvB3paCxCeE30wpic/YzpjwQ1vx4c5WwGEmV2amLyqZJFFdfuyP1lKCZ90GPBqz
6gSVXksan6LyngitnqFnrCbo8oGTariB7tKHwDdpQla2I3ykg9YtZW9Azm0FUl9s
GJPlAoGAVE9+xei52k7Gv2dtaoEzZXONHviA0C+eO9VIOEKmlafDBxKij2pKNmxC
ARJxdY5PQQNbtSJIZ1S/GLyzhce8Vr9vdF9AM+mSQOQlEFECJ80NR8sSJJ7Judo5
j5a4n+8J+cSLLXn85PBskE2T23h+WHQqm0pG5qAlqwYBdGxZcmY=
-----END RSA PRIVATE KEY-----

Now you can digest the cert in whatever format your use case requires!

---
tlsCertOne: "string\nform\n..."

tlsCertTwo: |
  multi
  line
  form
  ...
...

Extra Credit

A friend and former colleague pointed out many APIs want certificates Base64 encoded. Kubernetes is one big example where you will use Base64 a lot. Luckily, it's easy to encode and decode:

❯ myString="some string of text"

❯ echo -n $myString | base64
c29tZSBzdHJpbmcgb2YgdGV4dAo=

❯ base64String=$(echo -n $myString | base64)

❯ echo $base64String | base64 --decode
some string of text
Show Comments