How to validate opendkim generated RSA keys

I'm trying to diagnose OpenDKIM validation errors (see this question). Way down in the belly of the beast, I'm at the point where I'm trying to make sure the keys generated are actually correct.

I'm generating my keys with opendkim-genkey -r -d example.com. This generates two files. One is an RSA private key (file default.private):

-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDJy9S18vHtrIQNep9PogJfrKNLKKf2VSOvUwOzItlWkY3cRCFx
scSNjfC4QHREcMeUuNO78wvQ+oOk+exLdyl2BggcA659Wi6v8X/+awLXpa9sB6vi
GPi8Zx560GbZu6jGLlEzcOaGDCYqdUxZIdAaOICDORFa3XAywHi87eQPMwIDAQAB
AoGAVSjAvnwlHqEEJVAPNSLwj4Gic9BXeXwakB2fXRSi1YadcEwMNRfJE9fHs2n3
5v4VK60IJbP+05U0wwV5c6t5AgZqpP0GBW8CKUr3BwaF2cJbd+uOXlAm4cx6/S1E
Ocoku0c/vrr3mkO41IuBkB+FRm0y7WXFi7e7M32Tictt0CkCQQDzE08wRLNXxkaM
LyUDMvCtlNzACcmkU73NAHDHhwtrJMMLp7q/s4VIDbmhysoNBblNHJQvA/7zVd13
1CGxbh8/AkEA1IajRLNJ6XTuv9RmK1622BDWix4ogEvbev/zR8ti2JifO6A5gv+L
na5hVAATo563pWjtNZW3sAVKqN7juN5HDQJAP1xKKP/Pa9LQMtxbHoFZwTVrcVdb
y0zUzaoOu8PU0yHrAY/AGxY1aLnDKIxOrKRQT+xiJ/s3qsA4EXMnMTPOSwJBAK5N
dl6EBRyZsK5YDyuG1MNEnBEhPOpsTKgGf4rkfj9SfVYzxLdxyxoZyO1R2smZBNl+
wv3tuud8j40MsQwQEYkCQBCzH+1IaxoMsSggutvEvqz2SqkFbD5rq/+uL6P6xyYg
PHCYIWomK8zOlmnO+bfbRIzQb7I81vOFq2sr0yQLK+0=
-----END RSA PRIVATE KEY-----

and one generates the DKIM DNS entry, which I assume contains the public key:

default._domainkey  IN  TXT ( "v=DKIM1; k=rsa; s=email; "
      "p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJy9S18vHtrIQNep9PogJfrKNLKKf2VSOvUwOzItlWkY3cRCFxscSNjfC4QHREcMeUuNO78wvQ+oOk+exLdyl2BggcA659Wi6v8X/+awLXpa9sB6viGPi8Zx560GbZu6jGLlEzcOaGDCYqdUxZIdAaOICDORFa3XAywHi87eQPMwIDAQAB" )  ; ----- DKIM key default for example.com

I'm assuming the "p=" entry is the public key, but if it is, I can't figure out how to verify if they match. I thought I could do this with ssh-keygen -y -f default.private, however, the output of that is distinctly different than what's in the "p=" section of the DNS entry (it's not even the same length):

# ssh-keygen -y -f default.private 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDJy9S18vHtrIQNep9PogJfrKNLKKf2VSOvUwOzItlWkY3cRCFxscSNjfC4QHREcMeUuNO78wvQ+oOk+exLdyl2BggcA659Wi6v8X/+awLXpa9sB6viGPi8Zx560GbZu6jGLlEzcOaGDCYqdUxZIdAaOICDORFa3XAywHi87eQPMw==

So, what's going on here? Is ssh-keygen not the right way to do this (maybe I should be doing something with OpenSSL?)? Is "p=" not the public key? Or, in fact, do my private and public keys not match?

Thanks!

PS, as a perhaps unrelated aside, what I'm assuming to be the public key generated by opendkim is always the same for the first 34 characters — MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQ — and always ends in IDAQAB.


Solution 1:

You can compare the modulus of both, as follows:

Grab the public key from your DNS record. This is the string within the p=, as you say. Be aware that it is sometimes returned as two strings, which you'll need to join. You only need the contents, less the double quotes. Save this locally, as public.key.b64.

Convert to DER format with:

openssl enc -base64 -d -in public.key.b64 -out public.key

View the modulus of this public key with:

openssl rsa -pubin -inform DER -in public.key -noout -modulus

View the modulus of your private key with:

openssl rsa -in private.key -noout -modulus

The output of both will be similar to the following and must match:

Modulus=B475A0F01B6DE62AB578E27CF2DF8F760C9C10DF52E69F4ED2FEA6912D8528F5860F6C1AB3F7DD88D4C63A1DA5A848D7655192FF6040E0405826648047EB25ECB0F56FDCB825987D48FA3953DCB04F78521F607137179C7EE081C48AF7DFB2F130E3001B80433977E962D900B9AFC9808F39B3D041213D39B5FA447EE39E838E67D5CD2EA373D68CFDB2DF3CD0260C6D7C88A7415195EEB85DBD31594E11D4BAD49C52098A8E77B56D034B04234A9064C92DBEB6A7B745EB9821446A56FF34284A0AA27768E55BF263E8D2F3B7BE52ECBE3F4590BAF7AD33DDECAD997DC61B8EAD2854714B13FAF7035758A21651740A9B36077ABC715080243626A1B3661233