I am trying to create a smart contract where I have to encrypt (and decrypt) data that I receive from a Python script running on a client. The data will be encrypted on the client-side, and I will have to decrypt it on the smart contract.
I got a smart contract code which can generate a key pair here. I am new to cryptography, and I tried looking up how I can encrypt plaintext using the public key and decrypt using the private key, but I am not getting a proper answer anywhere.
It will be great if someone can guide me to a relevant resource. Thank you.
Actually, this document does a pretty good job of going through the steps of using one particular Python elliptic curve library.
Note that you don't actually encrypt or decrypt large amounts of data using the public/private key. Instead, one uses ECC to create a shared secret key, and then that shared secret key is used with AES or whatever is your encryption algorithm of choice.
Related
Currently I started working with the cryptography framework on python. I'm trying to build a SSH Suit by my own but I ran into some problem with the library. I'm trying to build my own Elliptic Curve Key Exchange Init Packet (with scapy).
I'm trying to do an Elliptic Curve Diffie-Hellman key exchange with the curve secp256r1. I'm able to generate the key-pair on my client with out any problem. But after I created the public key object im kinda confused how to get the 32-byte public key for exchange via network packets.
my code so far (which doesn't work for me):
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import serilization
curve = SECP256R1()
peer_private_key = ec.generate_private_key(curve)
peer_public_key = peer_private_key.public_key()
peer_public_pkt = peer_public_key.public_bytes(encoding=serilization.Encoding.DER, format=serialization.PublicFormat.SubjectPublicKeyInfo)
But this peer_public_pkt is not 32 Byte long.
Another Problem is when i get like an ECDH Public Key Value via Scapy or Wireshark from a Server via Network i cant translate the value back with
srv_public_key = ec.EllipticCurvePublicKey.from_encoded_point(curve, data_from_wireshark)
I think I'm missing some crucial steps here but I looked at the documentation for two hours and into some older examples on different sites but I can't find help (or see the solution).
Hopefully you can help me :). If something about my problem is not clear just ask.
EllipticCurvePublicKey.from_encoded_point takes compressed/uncompressed points. You can obtain those from public_bytes via a format of PublicFormat.CompressedPoint and format of Encoding.X962. SubjectPublicKeyInfo DER serialization is an ASN.1 format with additional structure.
Your assumption of 32 bytes on a secp256r1 key is also incorrect, as a compressed public point adds one byte defining the sign for unambiguous point reconstruction.
I was able to encode a string with uuid_3 but I can not figure out a way to decode it.
My code to encrypt:
new_id = uuid.uuid3(uuid.NAMESPACE_URL, url)
You will not be able to decrypt your uuid. uuid3 is based on an md5 hash, which is an irreversible hashing algorithm. A uuid really shouldn't be relied upon for encryption anyways, since they are just identifiers. There are encryption/decryption schemes designed for this such as foreign key encryption and symmetric key encryption, to name a few.
new to Python, been using it for a few months. One of my morning tasks is to encrypt a set of files and upload them to an FTP. It’s a very tedious task I was hoping to automate.
The current keys came from the program PGP Desktop and have created public/private keys to encrypt files and eventually upload to an FTP. The same keys are used every day.
Is there a way to encrypt a file using the already existing key(s) on my machine (as I know where they’re kept) to encrypt a file using python. The only articles I’ve found on SO involve creating a new key using python. Just wanting to bypass the morning ritual of right click > ‘Secure file with key…’. Currently we use no signing key, so it’s just the key for encrypting I need to use.
I struggle to understand the correct use of an IV (Initialization Vector) when encrypting data in AES.
Precisely, I'm not sure where to store my randomly generated IV: in my script, the data will be encrypted, then saved to a file, then the program will terminate. During the next session, the previously saved data must be decrypted. If my understanding of IVs is correct, I have to use the same IV for decryption as for encryption (but another random-IV for every single encryption process).
Thus, I have to store the IV somewhere - some people recommend prepending it to the encrypted data, but if I get it right that won't work in my case, because I need the IV in order to be able to decrypt it.
Is this correct or did I misunderstand something? I want to avoid saving the encrypted/hashed key and the IV (even if hashed itself) inside some unencrypted plain-text-settings-file or something.
The IV itself is not sensitive data; its just used to scramble the state of the first cipher-text block and the scrambling is not recoverable from the IV itself (the key adds in the "secret" factor).
For "proper" chaining modes the IV is separate from the cipher text (you need the initial IV for both encryption and decryption) and must be stored separately and passed separately to the crypto library API. After encryption you can store the IV however you like - just don't lose it ;).
You can certainly "prepend" / "append" to the cipher text so you only have to store a single blob of data - but you'll just have to split it off prior to decryption as that is what the API will expect.
The "unproper" way to do an IV (e.g. if your crypto library API doesn't have native IV support, but does support chaining) is just to prepend a single block of random data to the plaintext before encrypting it. In this case there isn't any IV to store separately - you simply encrypt the entire IV+message binary pair - and then you simply delete the first block of data after decrypting it. The "random data" you prepend has the same constraints as a real IV (don't reuse the same random data with the same key, etc).
The two approaches are semantically different at the API level, but the effect on the actual encryption is the same (scamble the first block of real payload unpredictably).
In terms of how the IV is used - there are many possible schemes. See the wikipedia article on block chaining here for a convenient picture showing how the IV can be used in various chaining modes when it is really store separately.
https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation
I want to apply an AES 128b encryption (probably CBC + Padding) on a data stream.
In case it matters, I'm sending chunks of around 1500bits each.
I work in Python, and I did a small test with M2Crypto with AES encrypt in one side and decrypt at the other side. It works perfect, but probably don't really secures anything since I use the same key, same IVS and all that.
So, the question is: What the best approach for AES encryption on large data streams?
I thought about loading a new 'keys' file from time to time. Then, the application will use this file to expend and extract AES keys or something like that, but it still sounds awful to build a new AES object for each chunk, so there must be a better way.
I believe I can also use the IVS here, but not quite sure where and how.