I want to decrypt ssh traffic in a virtual environment such as OpenNebula.
For this purpose I extracted the six ssh keys (IVs, Encryption keys and integrity keys) from the function key_derive_keys from the openssh/opensshportable code.
If I then trace a ssh connection between a server and a client I can decrypt traffic if the two parties use AES-CBC mode without problems.
But when the parties use AES-CTR the keys derived from the same method are no longer working.
So my question is: Do I maybe extract the wrong IV? So do I have to trace a different function/struct?
My code for the AES-CTR is:
key="1A0A3EBF96277C6109632C5D96AC5AF890693AC829552F33769D6B1A4275EAE2"
iv="EB6444718D73887B1DF8E1D5E6C3ECFC"
key_hex=binascii_a2b_hex(key)
iv_hex=binascii_a2b_hex(iv)
aes = AES.new(key_hex, AES.MODE_CTR, initial_value = iv_hex, nonce=b' ')
decrypted = aes.decrypt(binascii.a2b_hex(cipher).rstrip())
print(decrypted)
Edit: created a new thread for a related but vers similar Problem here: Get the counter value after decrypt finished
Maybe someone has an idea?
Edit: I fixed the problem meanwhile. The problem was that the counter is already incremented at the authentication step, which means that when the encryption starts the counter is a little bit higher than the IV.
Which means that I had the correct keys, but the counter was wrong. I let this thread open for any one interessted.
Related
I'm searching for a python library that is capable if decrypting and encrypting RSA (RSA_PKCS1_PADDING to be precise) with a public key. I've aleready tried pycryptodome, cryptography and rsa and all of them cannot decrypt using public key. I have searched through hundreds of posts, and all answers are useless, so to filter them:
I am not confusing a public key with a private key
Public decryption is possible (I was able to do it here)
There is no other way around. I literally need to send public encrypted messages to the server, and recieve private encrypted messages and decrypt them with the public key
Ideally it should be something like nodejs's crypto.publicDecrypt() and crypto.publicEncrypt(). Please help me to find even if not a library, but just a function that is capable of doing it. I looked through the hundreds of posts and I'm feel like I'm going insane. Thank you.
It is as you say indeed possible to encrypt with private and decrypt with public, the mathematical symmetry in RSA allows just swapping e/d in the keys and then calling the encrypt/decrypt functions.
This being said, I want to emphasize that I'm not a crypto expert and cannot say for certain that this doesn't compromise security.
So, you could extend the RSA-Key class with that swapped logic, use blackmagic to swap the implementation of the loaded key, and pass it to the normal functions:
from Crypto.PublicKey.RSA import RsaKey
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from Crypto.Math.Numbers import Integer
class SwappedRsaKey(RsaKey):
def _encrypt(self, plaintext):
# normally encrypt is p^e%n
return int(pow(Integer(plaintext), self._d, self._n))
def _decrypt(self, ciphertext):
# normally decrypt is c^d%n
return int(pow(Integer(ciphertext), self._e, self._n))
data = "I met aliens in UFO. Here is the map.".encode("utf-8")
# It's important to also use our swapped logic in encryption step, otherwise the lib would still use e&n (the private contains all 3 values).
private_key = RSA.import_key(open("mykey.pem").read())
private_key.__class__ = SwappedRsaKey
public_key = RSA.import_key(open("mykey.pub").read())
public_key.__class__ = SwappedRsaKey
cipher_priv = PKCS1_OAEP.new(private_key)
cipher_pub = PKCS1_OAEP.new(public_key)
enc_data = cipher_priv.encrypt(data)
# Decrypt again, just a showcase to prove we can get the value back
dec_data = cipher_pub.decrypt(enc_data)
print(dec_data.decode("utf-8"))
First of all, big thanks to Tobias K. for the short and clear answer. It worked flawlessly.
But when I tried to decrypt the server messages, pycryptodome kept returning sentinel instead of decrypted data. I decided to look into the library source code, and check what would .decrypt() return if I comment out this lines in .../Crypto/Cipher/PKCS1_v_1_5.py:
if not em.startswith(b'\x00\x02') or sep < 10:
return sentinel
And to my surprise it returned the decrypted message! Not sure that I didn't break something, but it works. I guess it was a bug? This is aleready fixed in their github repo, but the version is not released yet
I have some data in a python program that I'd like to encrypt before writing to a file with a password, and then read it and decrypt it before using it. I'm looking for some secure symmetric algorithm that can encrypt and decrypt against a password.
This question shows a non-secure way and suggests using libsodium. Since I'm using Python, I found pysodium. It seems to have tons of functions mapped from libsodium, but I don't know how to simply encrypt/decrypt data against password.
My problem is that it looks like all encryption algorithms use keys. I don't want to use keys. I want to only use a password. Just like what I do in the terminal:
To encrypt:
$ cat data | openssl aes-256-cbc -salt | dd of=output.des3
To decrypt:
$ dd if=output.des3 | openssl aes-256-cbc -d -salt
Is it possible to do this with pysodium (in a cross-platform way, so please don't suggest using a system call)?
So my question reduced to: "How can I encrypt data against a password in Python". I gave up on pysodium due to the lack of documentation. I used cryptography and argon2 packages to write my own encryption algorithm (it's not my own crypto algorithm, I know Rule No. 1 in crypto; it's just the procedure to utilize what's already there). So here are my functions:
import cryptography.fernet
import argon2
import base64
def encrypt_data(data_bytes, password, salt):
password_hash = argon2.argon2_hash(password=password, salt=salt)
encoded_hash = base64.urlsafe_b64encode(password_hash[:32])
encryptor = cryptography.fernet.Fernet(encoded_hash)
return encryptor.encrypt(data_bytes)
def decrypt_data(cipher_bytes, password, salt):
password_hash = argon2.argon2_hash(password=password, salt=salt)
encoded_hash = base64.urlsafe_b64encode(password_hash[:32])
decryptor = cryptography.fernet.Fernet(encoded_hash)
return decryptor.decrypt(cipher_bytes)
And here's an example on how to use them:
cipher = encrypt_data("Hi Dude, Don't tell anyone I said Hi!".encode(), "SecretPassword", "SaltySaltySalt")
decrypted = decrypt_data(cipher, "SecretPassword", "SaltySaltySalt")
print(cipher)
print(decrypted.decode())
Remember that encryption is for bytes only; not for strings. This is why I'm using encode/decode.
Why argon2? Because it's a memory hard algorithm that's very hard to break with GPUs and ASICs (yes, I'm a cryptocurrency fan).
Why Fernet? Because it uses AES CBC, which seems to be secure enough; besides, it's really easy to use (which is exactly what I need... I'm not a cryptographer, so I need a black-box to use).
Disclaimer: Please be aware that I'm not a cryptographer. I'm just a programmer. Please feel free to critique my way of encrypting and decrypting, and please feel free to add your contribution to make this better.
i am new to python. I have some experience with Pascal and a little bit with C++.
At the moment i have to program some code for a research project demonstrator.
The setup is as follows:
We have a 868MHz radio master device. i can communicate with this device via a USB port (COM4 at the moment but may change in the future).
The 868MHz master communicates with a slave unit. The slave unit replies with a message that i can read from the USB port.
Until this point everything works good. I request data packages and also receive them.
From the moment of receiving the data packages i have a propblem i seem not
able to solve on myself.
I use Anaconda 32 bit with the Spyder editor
# -*- coding: utf-8 -*-
"""
Created on Thu May 7 13:35:59 2015
#author: roland
"""
import serial
portnr = 3 #Serial Port Number 0=Com1, 3=Com4
portbaud = 38400 #Baud rate
tiout = 0.1 #Timout in seconds
i = 1
wrword = ([0x02,0x04,0x00,0x00,0x00,0x02,0x71,0xF8])
try:
ser = serial.Serial(portnr, portbaud, timeout=tiout) # open port
except:
ser.close() # close port
ser = serial.Serial(portnr, portbaud, timeout=tiout) # open port
print(ser.name) # check which port was really used
while (i < 100):
ser.write(wrword)
seread = ser.readline()
print(seread)
i = i+1
sere = seread.split()
try:
readdat = str(sere[0])
except:
print("Index Error")
retlen = len(readdat)
print(retlen)
readdat = readdat[2:retlen-1]
print(readdat)
ser.close() # close port
The variable wrword is my request to the 868MHz radio master.
The Format is as follows:
0x02 Address of the unit
0x04 Command to send information from a certain register range
0x00 0x00 Address of first Register (Start address 0 is valid!)
0x00 0x02 Information how much registers are to be sent (in this case Registers 0 and 1 shall be transmitted to the Radio master)
0x71 0xF8 Checksum of the command sentence.
The program sends the command sequence successful to the master unit and the slave unit answers. Each time the command is send an answer is expected. Nevertheless it may happen that now correct answer is given thats why the
try command is in use.
I know i use ser.readline() but this is sufficient for the application.
I receive a list as answer from the USB Port.
The data look as follows:
b'\x02\x04\x04\x12\xb6\x12\xa5\xe0\xc1' (This is the Output from print(seread) )
For clarification this answer is correct and must be read as follows:
\x02 Address of the answering unit
\x04 Function that was executed (Read from certain register area)
\x04 Number of Bytes of the answer
\x12 \xb6 Value of first register (2 Byte)
\x12 \xa5 Value of second register (2 Byte)
\xe0 \xc1 Checksum of answer
If the data from the com port had all this Format i might be able to get the data values from the both Registers. But unfortunately the data format is not always the same.
Sometimes i receive answers in the following style:
b'\x02\x04\x04\x12\x8e\x12{\xe1T'
The answer is similar to the example above (different values in the Registers and different checksum) but the Format i receive has changed.
If i use the hex ASCII codes for the symbols obviously not hex values i find a valid answer telegram.
b'\x02\x04\x04\x12\x8e\x12{\xe1T'
becomes
b'\x02\x04\x04\x12\x8e\x12\x7b\xe1\x54'
when i Exchange the ASCII symbols by their hex code by Hand.
So my questions are:
Is it possible to force Python to give me the answer in a defined Format?
If not is it possible to handle the list or the string i can derive from the list in such a way that i get my values in the required format?
Does somebody can give me a hint how to extract my register values from the list and convert the two hex numbers of each register into one integer value for each register (the first value is the high byte, the second the low byte)?
Thanks in advance for your answer(s)
sincerely
Roland
I found a solution.
During a small testpiece of program i stumbled upon the fact that the variable seread contains already the data in a suitable and usable format for me.
I assume that the Spyder Editor causes the format change when displaying byte type objects.
If i Access the single Bytes using seread[i] while i is in range 0 to len(seread)-1 i receive the correct values for the single bytes.
So i can acess my data and calculate my measurement values as required.
Nevertheless thanks to keety for reading my question.
I'm working on generating voucher code.
Current case is:
Voucher is ranging from 0-999, and generated once a week with an unique code for each voucher.
Can be verified later to check validity.
There's a secret key for each week, I used the random generated secret key to encrypt the voucher number to code.
I've found out that the code is guessable, for example:
'002' => '\xec\xbe\x98'
'003' => '\xec\xbe\x99'
then I tried to use MD5 to hash the code but it's too long(32 digit), and can be time consuming as I wrap the code in a qrcode for the voucher that I generate.
currently I'm using pycrypto module with CFB mode AES encryption,
can anyone tell me which is a preferred method to generate a verifiable voucher code ?
The Hashids module is probably what you're after:
from hashids import Hashids
hash_id = Hashids(salt='your_secret_here', min_length=8)
hash_id.encrypt(0) # aDnwJKQZ
hash_id.encrypt(999) # p32jAqVW
# it is reversible
hash_id.decrypt('p32jAqVW') # (999,)
It has some good features for voucher code generation such as curse word filtering and configurable alphabet.
It is not a hardened encryption solution but for voucher codes with limited value I'm sure it would provide enough protection from brute-force attack, especially if you change the secret each week.
I am dealing with the Box.com API using python and am having some trouble automating a step in the authentication process.
I am able to supply my API key and client secret key to Box. Once Box.com accepts my login credentials, they supply me with an HTTP GET parameter like
'http://www.myapp.com/finish_box?code=my_code&'
I want to be able to read and store my_code using python. Any ideas? I am new to python and dealing with APIs.
This is actually a more robust question than it seems, as it exposes some useful functions with web dev in general. You're basically asking how to separate my_code in the string 'http://www.myapp.com/finish_box?code=my_code&'.
Well let's take it in bits and pieces. First of all, you know that you only really need the stuff after the question mark, right? I mean, you don't need to know what website you got it from (though that would be good to save, let's keep that in case we need it later), you just need to know what arguments are being passed back. Let's start with String.split():
>>> return_string = 'http://www.myapp.com/finish_box?code=my_code&'
>>> step1 = return_string.split('?')
["http://www.myapp.com/finish_box","code=my_code&"]
This will return a list to step1 containing two elements, "http://www.myapp.com/finish_box" and "code=my_code&". Well hell, we're there! Let's split the second one again on the equals sign!
>>> step2 = step1[1].split("=")
["code","my_code&"]
Well lookie there, we're almost done! However, this doesn't really allow any more robust uses of it. What if instead we're given:
>>> return_string = r'http://www.myapp.com/finish_box?code=my_code&junk_data=ohyestheresverymuch&my_birthday=nottoday&stackoverflow=usefulplaceforinfo'
Suddenly our plan doesn't work. Let's instead break that second set on the & sign, since that's what's separating the key:value pairs.
step2 = step1[1].split("&")
["code=my_code",
"junk_data=ohyestheresverymuch",
"my_birthday=nottoday",
"stackoverflow=usefulplaceforinfo"]
Now we're getting somewhere. Let's save those as a dict, shall we?
>>> list_those_args = []
>>> for each_item in step2:
>>> list_those_args[each_item.split("=")[0]] = each_item.split("=")[1]
Now we've got a dictionary in list_those_args that contains key and value for every argument the GET passed back to you! Science!
So how do you access it now?
>>> list_those_args['code']
my_code
You need a webserver and a cgi-script to do this. I have setup a single python script solution to this to run this. You can see my code at:
https://github.com/jkitchin/box-course/blob/master/box_course/cgi-bin/box-course-authenticate
When you access the script, it redirects you to box for authentication. After authentication, if "code" is in the incoming request, the code is grabbed and redirected to the site where tokens are granted.
You have to setup a .htaccess file to store your secret key and id.