I have a string secret that I would like to encrypt for storage in a Yubikey's second slot. These slots can be configured to store up to 38 characters that are later "typed" by the USB device acting as a keyboard. This means it can't store raw bytes, but fortunately it's sufficient for my use case for my secret to consist of 38 base64 characters.
Using a strong password, I'd like to use OpenSSL v1.0.1+'s implementation of aes-256-ctr
to encrypt the secret for storage on the Yubikey. I am asking about using a counter cipher rather than an alternative because I need for the output to have the same number of bytes as the input. I also need to decode the input from base64 first so that it's using the bytes efficiently, and then encode it as base64 again after the encryption so that the result can be "typed".
echo -n "secret+that+is+exactly+38+base64+chars" | \
openssl enc -base64 -A -d | \
openssl enc -base64 -aes-256-ctr -nosalt -k "this will be a strong password"
Is this a secure way to store my secret? Would it be safe to, say, post the encrypted secret on the public Internet? I'm not planning to, but I also don't want to have to be constantly vigilant about the physical security of the Yubikey itself.
Edit: Thanks for the answers and comments! I apologize for having left some things ambiguous initially, but my lack of domain knowledge made it difficult to know what's relevant. Here are some clarifications:
- The Yubikey functionality I'm using is called Static Password mode. While the Advanced configuration for this mode can contain 64 modhex characters, the user cannot choose the password so this does not match my use case. The alternative is the Scan Code configuration which can store up to 38 ASCII 256 characters. I can select either US or DE keyboards in the Yubikey Personalization Tool that I'm using to configure the device; as I understand it, this determines the scan codes that are emitted to correspond to my saved password, and a US keyboard will work for me. I realize this is 4x the different characters I get from base64, but since I was able to get something that seemed to work as-is, I didn't try to convert the encrypted bytes to ASCII 256 for more efficient storage. Links: Yubico knowledge base, PDF documentation (see page 25), scan code explanation.
- The secret I'm planning to encrypt and store is a 1Password Secret Key, so it will have 128 bits of entropy. (I removed some dashes to make it fit the 38 characters, and converted the remaining dashes to pluses.) I'm trying to set up a recovery plan that is more accessible than a piece of paper in a safety deposit box, and more secure and durable than a piece of paper in my wallet. I omitted this detail from my original question because it seemed like a distraction, but I see now it's relevant to certain types of attacks.
- I was planning to use a proper diceware password with at least seven words. If I use ten for 128 bits, is my original proposal sufficient?
- I'd love to find a way to make this work securely with the standard tools in OpenSSL. Part of the reason for this is that other tools (such as argon2) seem a bit over my head / beyond what I can trust myself to use properly. Most of the reason, however, is that I want to use tools that are at least somewhat universally accessible so that I'm able to decrypt my 1Password Account Key and recover from hardware loss in the widest variety of possible circumstances (i.e. if I'm abroad without my laptop). One appealing thing about OpenSSL ciphers is that there are Javascript implementations that I could use on a trusted iPhone to do the decryption, obviating the need to install and use OpenSSL on some unknown machine. I was able to get the above encryption/decryption to work using Forge, for example.