How to understand the difference between these encoded strings? - python-3.x

Test Text: username
Encryption Result:
uname1 = b'\x01\x02\x02\x00x]n\xe8\xe6\xae\xae\xdf\xb7F\x87^!\xc1l8\x0eC\xb0\xcc\xf5\x00\xe7%j\xa2S\xc7\x84\xb4\xf2\xea]\x01K\xf9\xf9\xe7c\xa7\xc8A\xec\xf3\xd1\x9f\xd9\x9f\x86\xb7\x00\x00\x00f0d\x06\t*\x86H\x86\xf7\r\x01\x07\x06\xa0W0U\x02\x01\x000P\x06\t*\x86H\x86\xf7\r\x01\x07\x010\x1e\x06\t`\x86H\x01e\x03\x04\x01.0\x11\x04\x0c;\xaa\xe9\x03\x84\x00Z\x96"\t/\x18\x02\x01\x10\x80#\xdd\xf1C\xafy\x1e\xf07Z\x0fI_\ncr\x80\xdc\xf5>o\xb9`\x1a\xf8\x0c\xec\x0f\xc3\xd1\x8f\xdd\xe6~\xca\x16'
Supposedly the following is also the result of username being encrypted by KMS and I have to decrypt it:
uname2 = "AQICAHiRhVOkDetQTv51rimwyQpfSKJYi6zefQF+Wz32zFAYKwEyMctEfb/Oos0Mq48uPt2AAAAAZjBkBgkqhkiG9w0BBwagVzBVAgEAMFAGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQM7vxxEHGmH5vHJX1zAgEQgCM2Uee6e6zM0mQgli9kXQVJ3pNid+waG6nrDnB9P3VjVquaCA=="
Decrypting uname1 works just fine but uname2 does not work and results in the following error:botocore.errorfactory.InvalidCiphertextException: An error occurred (InvalidCiphertextException) when calling the Decrypt operation:
Documentation I was following: https://docs.aws.amazon.com/kms/latest/developerguide/programming-encryption.html
I am trying to decryptuname2, uname1 was just a local test I did.
Is this a character encoding issue? Why do the strings look so different?

You simply need to decode the uname2 string, as it is Base64 encoded after being encrypted. You will then be able to decipher it.

Related

How to encrypt a password using MD5-DES?

I'm looking for any available tool/shell command which can encrypt passwords using as algorithm "masked-MD5-DES". The masked password must be then converted into base64, but that should be the easy part.
In the only working example I have found, the string "password" is encrypted as "j37uUs8kG9t2QSWjoxxtDg=="
<credentials>
<masked-password iteration-count="12" salt="12345678" masked-password="j37uUs8kG9t2QSWjoxxtDg=="/>
</credentials>
Can you help me to generate that masked password from the clear text "password" ?
I have tried with:
echo "password" | md5sum | base64
However the result does not match with "j37uUs8kG9t2QSWjoxxtDg==".
Any help is greatly appreciated.
EDIT: As requested by comment, I've added a reference to the document which contains the algorithm to be used in the application: https://github.com/wildfly/wildfly-proposals/blob/master/elytron/ELY-816-masked-password.adoc
Thanks

cryptography.Fernet why does decrypt still work on modified token

I am a new user of py-cryptography. I am finding that even the encrypted token is modified at end, it still decrypts OK. How so?
Here is a test script
from cryptography.fernet import Fernet
f = Fernet( Fernet.generate_key() )
word = b"very secret thing"
print("encrypting...", word)
token = f.encrypt( word )
print("decrypting...", len(token), token,)
reword = f.decrypt( token )
print("works as expected" if reword == word else "oops!")
modtoken = str.encode( token.decode() + "?abcd." )
print("modified token, appended stuff")
print("decrypting...", len(modtoken), modtoken)
reword = f.decrypt( modtoken )
print("whoops! still decrypts ok" if reword == word else "good boy!")
and the output was
encrypting... b'very secret thing'
decrypting... 120 b'gAAAAABb3TIJLCgbVdq-CgQ3V7V3eehQ02h_O70iZkCjd6KCU9GsErog-c-LluWITQg5lTsp5ldoTc0J_XdFCd-jhoJPOYAKyQbzbHDJZKTGORIJSflO1do='
works as expected
modified token, appended stuff
decrypting... 126 b'gAAAAABb3TIJLCgbVdq-CgQ3V7V3eehQ02h_O70iZkCjd6KCU9GsErog-c-LluWITQg5lTsp5ldoTc0J_XdFCd-jhoJPOYAKyQbzbHDJZKTGORIJSflO1do=?abcd.'
whoops! still decrypts ok
Is this expected behavior? If so, how do I check if the token is not modified between encrypt and decrypt?
python 3.6.6 on ubuntu under WSL
cryptography - github.com/pyca/cryptography
---EDIT---
I changed the line
word = b"very secret thing"
to
word = b"very secret thing XXXXXXXXXXXX"
and the effect was (1) the token length went from 120 to 140 (2) decrypting modtoken raised an Exception!
After reading Paul's answer I also am wondering if it would be wise to use this library in production code or if someone could suggest a suitable alternative.
This is an artifact of the malleability of base64 with Python's decoder. When the fernet token is base64 decoded everything you've added is discarded. This means that when the HMAC value is checked the ciphertext is untampered and the token passes.
While this is not directly a problem, it could become a problem if a user does something unwise with presumed token uniqueness. To be clear, Fernet has strong integrity guarantees for the token payload, but the base64 itself has limited malleability.
Over 3 years ago I tried to get the Fernet spec updated to require strict base64 encoding (https://github.com/fernet/spec/pull/11) but unfortunately the authors are not maintaining their spec and nothing has happened. We don't want to break compatibility with other Fernet implementations and this issue, while annoying, isn't enough to convince me that we need to fork it at this time.

Node.js crypto.publicEncrypt: 'Error: error:0906D06C:PEM routines:PEM_read_bio:no start line'

I'm trying to use the public key encryption in crypto.js, I want to encrypt some message using publicEncrypt, and decrypt it with privateDecrypt.
const crypto=require('crypto');
let alice=crypto.getDiffieHellman('modp14');
alice.generateKeys();
let enc=crypto.publicEncrypt(alice.getPublicKey(),Buffer.from('hello'));
However, the crypto.publicEncrypt line is causing the following error:
"Error: error:0906D06C:PEM routines:PEM_read_bio:no start line"
The public key value returned by crypto.DiffieHellman.getPublicKey() is just the raw DH number, optionally encoded in base64 or hex. It is not in (any) PEM format or even ASN.1/DER format (which could easily be turned into PEM). Similarly crypto.ECDH.getPublicKey() is only the point (in conventional X9.62 format), not any PEM or DER format.
Moreover, DH and ECDH are not encryption algorithms, they are key-agreement (or secret-agreement) algorithms, and that operation is performed by DiffieHellman.computeSecret() or ECDH.computeSecret() respectively. Although not clearly documented, publicEncrypt actually calls OpenSSL's EVP_PKEY_encrypt{_init,} which doesn't support DH or ECDH, only RSA (with several choices of padding) and possibly GOST-wrap (I can't easily verify that and it may well be version dependent because upstream OpenSSL as of 1.1.0 a few years ago dropped the GOST algorithms).
In short, you can't do that.

How can I import a .pfx file that was created without a password?

I have created a PFX PDU using the java bouncycastle library. Inside the PFX PDU, there are two certificates and two encrypted private keys. All the contents are used as PKCS#7 data content (i.e. no encryption, stored as octet strings).I organised the elements according to the guidelines of PKCS#12 (RFC 7292 Section 5). Then I wrote the DER encoded byte array to a file.
I opened the file in a hex editor and saw that the object structure is OK. I have also read the file contents and built a bouncycastle PFX object from it. But when I try to open the .pfx file from my file system, the Certificate Import Wizard asks for the password for the private key. I did not use any password to create the PFX object. I have tried to use empty string and the password used for encrypting the private keys, but they didn't work. It shows "The password you entered is incorrect.".
Is there something I missed here? How can I get the password required to import certificates?
In RFC 7292, section 4.1, page 41, details of AuthenticatedSafe is described. AutthenticatedSafe is sequence OF ContentInfo which could one of three types.
AuthenticatedSafe ::= SEQUENCE OF ContentInfo
-- Data if unencrypted
-- EncryptedData if password-encrypted
-- EnvelopedData if public key-encrypted
Make your authenticatedSafe data as EncryptedData where you needs to encrypt the BERencoded value of AuthenticatedSafe with the SecretKey generated from password you will give using SecretKeyFactory and PBEParameterSpec.
Hope that, this will help you. Cheers !!!

Node.js MD5 generates different result than htpasswd -m

when generating a password file using htpasswd -m -c file admin with the password admin the result looks like this:
cat file
admin:$apr1$V.aqW878$JCj8ivmSnFp3BnTCtLAuN.
When I try to authenticate against that using node.js the results are rather different:
Digest Hex: 21232f297a57a5a743894a0e4a801fc3
I've tried following this existing StackOverflow solution:
new Buffer('21232f297a57a5a743894a0e4a801fc3').toString('base64');
MjEyMzJmMjk3YTU3YTVhNzQzODk0YTBlNGE4MDFmYzM=
So the result was still wrong.
When I change the digest to base64 the result would be:
ISMvKXpXpadDiUoOSoAfww==
Bottom line of my problem is that I don't get the same hashes and need help. Any advice would be greatly appreciated.
Thank you
Roman
Alright, I found the answer. htpasswd uses a "salt" which is stored in the middle bit of the password string:
$apr1$V.aqW878$JCj8ivmSnFp3BnTCtLAuN.
Salt: V.aqW878
The node-pass module gave me the right clues. See validate_md5. It uses the native openssl command to generate a salted MD5 hash.
In retrospect this makes sense since MD5 isn't safe anymore. That's the reason I didn't use it for years now and got a bit off track here. In essence, anything marked with $apr1$ is to be treated like this.

Resources