Python ECDH with Cryptography Problem Public Key - python

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.

Related

Elliptic Curve encryption and decryption on Solidity and Python

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.

Signing parts of a URL with a RSAKey using Python instead of C#

I do have a private RSAKey (in XML format) that was generated by a .NET class. Those keys, are regularly used to sign parts of a URL. I am trying to sign these URLs with the existing keys via Python, because I am working now in a Linux based environment. The structure of the RSAKey looks like so:
RSAKeyValue,Modulus,Exponent,P,Q,DP,InverseQ,D represented in XML format.
Using C#, I simply instantiate a RSACryptoServiceProvider object and call SignData(bytes, new SHA1CryptoServiceProvider()), and I am done.
I have tried for several days now to replicate this process using Python in a Linux environment without any luck. I extracted modulus, and exponent, base64 decoded, and created byte arrays from them. I also changed the byte order. I was under the assumption that I could use M2Crypto and call RSA.new_pub_key((e,n)) and use that key to sign but no matter what I do I either can't create a proper key, or the signing process doesn't work.
My questions are:
-Is it possible to use an RSAKey in XML format that was generated via .NET, and sign data via Python (M2Crypto or any other lib will do) with the exact same result as in .NET ?
If so, what are the exact steps to do so?
My apologies for the long question. Thanks for any help.

Extract signing certs from a PKCS7 SignedData structure with m2crypto

I am trying to use M2Crypto to extract the signing certificates from a Windows PE file. According to the MS specification the data is stored in a PKCS#7 SignedData structure (stored in ASN.1 format, not the base64). I can't seem to get the binary format to load since it is not in PEM.
Pardon my ignorance with the crypto suites involved here, but if someone can show me the basics of how to get the signing certs out of a SignedData block I'd be most thankful!
If it helps, i found another solution for my problem but it is in C... how to Read the certificates file from the PKCS7.p7b certificate file usind openssl? If i could convert that to m2crpyto i'd be set.
I think there's more to this than just reading the certificate in PKCS7, unless you know absolutely what the offset & struct are.
You might want to take a look at either:
http://msdn.microsoft.com/en-us/library/aa380395(v=VS.85).aspx for the extraction process
Or possibly
http://msdn.microsoft.com/en-us/library/system.reflection.assemblyname.getpublickey%28VS.80%29.aspx
Additionally, it looks like Microsoft signs with a 'PFX' formatted file (I'd never heard of it before..)
But, I was able to find instructions on converting PFX back to a PEM, which should be a cakewalk to extract.
http://support.citrix.com/article/CTX106028

Python: How to transfer varrying length arrays over a network connection

I need to transfer an array of varying length in which each element is a tuple of two integers. As an example:
path = [(1,1),(1,2)]
path = [(1,1),(1,2),(2,2)]
I am trying to use pack and unpack, however, since the array is of varying length I don't know how to create a format such that both know the format. I was trying to turn it into a single string with delimiters, such as:
msg = 1&1~1&2~
sendMsg = pack("s",msg) or sendMsg = pack("s",str(msg))
on the receiving side:
path = unpack("s",msg)
but that just prints 1 in this case. I was also trying to send 4 integers as well, which send and receive fine, so long as I don't include the extra string representing the path.
sendMsg = pack("hhhh",p.direction[0],p.direction[1],p.id,p.health)
on the receive side:
x,y,id,health = unpack("hhhh",msg)
The first was for illustration as I was trying to send the format "hhhhs", but either way the path doesn't come through properly.
Thank-you for your help. I will also be looking at sending a 2D array of ints, but I can't seem to figure out how to send these more 'complex' structures across the network.
Thank-you for your help.
While you can use pack and unpack, I'd recommend using something like YAML or JSON to transfer your data.
Pack and unpack can lead to difficult to debug errors and incompatibilities if you change your interface and have different versions trying to communicate with each other.
Pickle can give security problems and the pickle format might change between Python versions.
JSON is included in the standard Python distribution since 2.6. For YAML there is PyYAML.
You want some sort of serialization protocol. twisted.spread provides one such (see the Banana specification or Perspective Broker documentation). JSON or protocol buffers would be more verbose examples.
See also Comparison of data serialization formats.
If you include message length as part of the message, then you will know how much data to read. So the entire string should be read across the network.
In any case, perhaps it would help if you posted some of the code you are using to send data across the network, or at least provided more of a description.
Take a look at xdrlib, it might help. It's part of the standard library, and:
The xdrlib module supports the External Data Representation Standard as described in RFC 1014, written by Sun Microsystems, Inc. June 1987. It supports most of the data types described in the RFC.
Pack and unpack are mandatory?
If not, you could use JSON and YAML.
Don't use pickle because is not secure.

How to encode an RSA key using PKCS12 in Python?

I'm using Python (under Google App Engine), and I have some RSA private keys that I need to export in PKCS#12 format. Is there anything out there that will assist me with this? I'm using PyCrypto/KeyCzar, and I've figured out how to import/export RSA keys in PKCS8 format, but I really need it in PKCS12.
Can anybody point me in the right direction? If it helps, the reason I need them in PKCS12 format is so that I can import them on the iPhone, which seems to only allow key-import in that format.
If you can handle some ASN.1 generation, you can relatively easily convert a PKCS#8-file into a PKCS#12-file. A PKCS#12-file is basically a wrapper around a PKCS#8 and a certificate, so to make a PKCS#12-file, you just have to add some additional data around your PKCS#8-file and your certificate.
Usually a PKCS#12-file will contain the certificate(s) in an encrypted structure, but all compliant parsers should be able to read it from an unencrypted structure. Also, PKCS#12-files will usually contain a MacData-structure for integrity-check, but this is optional and a compliant parser should work fine without it.
The standard tool for the job is typically OpenSSL.
See the openssl pkcs12 command.
This mailing list posting tends to suggest that PKCS12 is not planned for a future feature of that package, and is not currently implemented.
http://lists.dlitz.net/pipermail/pycrypto/2009q2/000104.html

Categories