-
-
Save paranoiq/1932126 to your computer and use it in GitHub Desktop.
#ssh-rsa AAAA[0-9A-Za-z+/]+[=]{0,3} ([^@]+@[^@]+)# | |
// this is the most simple case. see more complete regexps in coments below | |
// http://generator.my-addr.com/generate_ssh_public_rsa_key-private_rsa_key-ssh_pair_online_tool.php | |
// https://help.ubuntu.com/community/SSH/OpenSSH/Keys | |
// http://www.ietf.org/rfc/rfc4716.txt |
Thank you!
Sweet 👍
thanks
Yes, Thank you.
also adding sanity check with ssh-keygen -v -l -f .pub
Thank you!
public key without email must be valid, but in this regex email is required
#ssh-rsa AAAA[0-9A-Za-z+/]+[=]{0,3}( [^@]+@[^@]+)?#
Optional email version.
Thanks!
I tried to expand on this and an idea from https://stackoverflow.com/a/2494645/2256700 to include the possible headers in the Regex:
#^(ssh-rsa AAAAB3NzaC1yc2|ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNT|ssh-ed25519 AAAAC3NzaC1lZDI1NTE5|ssh-dss AAAAB3NzaC1kc3)[0-9A-Za-z+/]+[=]{0,3}( [^@]+@[^@]+)?$#
$ echo -n "\0\0\0\x07ssh-rsa" | base64
AAAAB3NzaC1yc2E=
$ echo -n "\0\0\0\x13ecdsa-sha2-nistp256" | base64
AAAAE2VjZHNhLXNoYTItbmlzdHAyNTY=
$ echo -n "\0\0\0\x0bssh-ed25519" | base64
AAAAC3NzaC1lZDI1NTE5
$ echo -n "\0\0\0\x07ssh-dss" | base64
AAAAB3NzaC1kc3M=
#^(ssh-rsa AAAAB3NzaC1yc2|ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNT|ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzOD|ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1Mj|ssh-ed25519 AAAAC3NzaC1lZDI1NTE5|ssh-dss AAAAB3NzaC1kc3)[0-9A-Za-z+/]+[=]{0,3}( .*)?$#
- Ecdsa can have 521 bit key
- The comment can be anything, not just email.
thanks guys : ]
cool thanks !!
OpenSSH 8.2+ now supports a new type of key that uses security keys (ex: yubikey) and begin with sk-
Using @notorand-it 's comment, this should validate keypairs with the sk-
prefix:
^(sk-)?(ssh-rsa AAAAB3NzaC1yc2|ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNT|ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzOD|ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1Mj|ssh-ed25519 AAAAC3NzaC1lZDI1NTE5|ssh-dss AAAAB3NzaC1kc3)[0-9A-Za-z+/]+[=]{0,3}( .*)?$
2022-06-16 Update:
I did some more digging and found the sk-
key types actually are not just simple prefixes.
I also found the above patterns for ecdsa-sha2-nistp384
, ecdsa-sha2-nistp521
, and ssh-dss
to be incomplete (missing the last character).
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNT
ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQ
<--Q
ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjE
<--E
[email protected] AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29t
<-- newssh-dss AAAAB3NzaC1kc3M
<--M
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5
ssh-rsa AAAAB3NzaC1yc2E
There are also other sk-
prefix types like sk-ssh-ecdsa
and surely other non-sk-
prefixed types.
All of these string that start with AAA
can be base64 decoded and should include some ascii characters and then the string they are encoding, ex:
AAAAC3NzaC1lZDI1NTE5
decodes to ����ssh-ed25519
@MaPePeR 's comment about using echo -n "\0\0\0\x0bssh-ed25519" | base64
(and other examples) is correct, but in his comment with the combined string he stripped off the trailing =
(which is correct to do) and then also the character before the =
which makes the strings incomplete. The ed25519
example is the only one that did not have a trailing =
so that one was correct (not truncated).
I also prefer using (\s.*)
instead of ( .*)
which should allow any whitespace character (ex: tab) instead of only allowing a standard space.
Here is a full regex pattern with the above (also sorted alphabetically):
^(ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNT|ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQ|ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjE|[email protected] AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29t|ssh-dss AAAAB3NzaC1kc3M|ssh-ed25519 AAAAC3NzaC1lZDI1NTE5|ssh-rsa AAAAB3NzaC1yc2E)[0-9A-Za-z+/]+[=]{0,3}(\s.*)?$
Personally I only plan to use:
^([email protected] AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29t|ssh-ed25519 AAAAC3NzaC1lZDI1NTE5|ssh-rsa AAAAB3NzaC1yc2E)[0-9A-Za-z+/]+[=]{0,3}(\s.*)?$
because I am only interested in [email protected]
, ssh-ed25519
, and ssh-rsa
.
@nemchik I left the last character out intentionally, because not all bits in that base64 character are part of the "known header data". There is additionally some padding in there, that determines the character:
\0 \0 \0 \0x7 s s h - r s a
|------||------||------||------||------||------||------||------||------||------||------|PADDING with 0
0000000000000000000000000000011101110011011100110110100000101101011100100111001101100001??
|----||----||----||----||----||----||----||----||----||----||----||----||----||----||----|
A A A A B 3 N z a C 1 y c 2 E?
Forcing the last character to be an E
also enforces, that the data that follows starts with 00
. I didn't know if that was always the case, so I didn't want to add that constraint to the regex. From all I know, these chars could be valid:
Last Header sextet | Base64 encoding |
---|---|
000100 |
E |
000101 |
F |
000110 |
G |
000111 |
H |
I didn't see the point going through all of them to determine these extra valid chars, when the regex can only give you a rough guideline anyway. But maybe there is also a constraint, that I don't know of, that forces these bits to always be 0
? Keeping the E
in the regex would be fine, then.
>>> import base64
>>> base64.b64encode("\0\0\0\x07ssh-rsa\x00")
'AAAAB3NzaC1yc2EA'
>>> base64.b64encode("\0\0\0\x07ssh-rsa\xFF")
'AAAAB3NzaC1yc2H/'
# ^- last character isn't an E anymore.
(I only picked rsa as the example here, because it was the shortest. But the same applies to all of them, of course)
@MaPePeR thanks for the follow up! That's super helpful! This comment thread is getting a bit large, so I'm considering making a repository where this could be kept up with and issues and pull requests could be opened to improve the information.
I'd want to include information such as removing characters from the end for the reasons you mentioned.
I've put together a repository here https://github.com/nemchik/ssh-key-regex
I've cited credit to @paranoiq for this gist and @MaPePeR for all of the amazing information provided here in the comments.
If I am made aware of new supported key types I will be happy to update the information or accept pull requests to improve.
A potential future goal will be to use GitHub pages to present the information as a webpage with nicer formatting.
Thanks! 👍