Importing RSA Key Pair from remote Machine - python-3.x

I'm fairly new to python but have basic understanding of crypto modules. However, I'm trying to import an RSA key pair from a remote machine(i.e. Safenet) to run some performance tests on signing data. I'm building the framework in Python and I haven't found many clear examples. For instance:
from Crypto.PublicKey import RSA
f = open('path/to/pair/00000103000003A2','r')
r = RSA.importKey(f.read(), passphrase='123456') # Index out of range error
print(r)
This is about as far as I'm getting with opening the key pair. I can import the key pair to my personal computer so it's in a directory I have access to.

I have found the answer elsewhere.
from OpenSSL import crypto
passwd = 'The password of your created .p12 file'
p12 = crypto.load_pkcs12(open("Path to p12 file.p12 ",'rb').read(),passwd)
print(p12.get_certificate()) #Prints object location
print(p12.get_privatekey()) #Prints object location
p12.get_ca_certificates()
Here's a link to convert object location to PEM formatted strings. PyOpenSSL convert certificate object to .pem file

Related

Not able to find number of pages of PDF using Python 3.X: DependencyError: PyCryptodome is required for AES algorithm

I am performing data validation on files that I download from a url. One of those validation checks involves checking the number of pages of a PDF. Using PyPDF2 package and PdfFileReader module, this worked until I encountered a PDF with 256-bit AES encryption that has a permissions password but no document open password. I have no access to any passwords since these files are from manufacturer websites so I concluded that for now I can just check to see if the PDF is encrypted, and if it is, skip it for now, but regardless if I try to retrieve the page count or check if the PDF is encrypted, I get this error:
DependencyError: PyCryptodome is required for AES algorithm
This error occurs at line 6, the if statement.
This is despite having pycryptodome installed and the AES module imported. Also, I am using Jupyter Notebook. Here is my code:
! pip install PyPDF2
! pip install pycryptodome
from PyPDF2 import PdfFileReader
from Crypto.Cipher import AES
if PdfFileReader('Media Downloaded Files/spk-10-3144 bro.pdf').isEncrypted:
print('This file is encrypted.')
else:
print(PdfFileReader('Media Downloaded Files/spk-10-3144-bro.pdf').numPages)
Solution:
! pip install pikepdf
from pikepdf import Pdf
pdf = Pdf.open('Media Downloaded Files/spk-10-3144-bro.pdf')
len(pdf.pages)
I had a problem using PyPDF3 (it's a fork from PyPDF2) involving encryptation. I solved replacing it for pikepdf. It has more encryption algorithms implementations. Try it out!

Python print all public key certificate information (X.509 Format)

I am trying to write a Python3 program which will show me all information which is included in a public key certificate, similar to the following linux command:
openssl x509 -in website.com.pem -text
which will return a result similar to
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
04:7a:f7:95:47:c0:7d:0f:ef:80:a5:b2:1f:51:e3:63
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Domain Validation Secure Server CA
Validity
Not Before: Mar 12 00:00:00 2018 GMT
Not After : Mar 11 23:59:59 2020 GMT
Subject: OU = Domain Control Validated, OU = PositiveSSL, CN = acs.cdroutertest.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
as shown on the following website: https://support.qacafe.com/knowledge-base/how-do-i-display-the-contents-of-a-ssl-certificate/
I was trying the Cryptography or pyopenssl modules in python3 already, and was able to import the certificate and display e.g. the public key. However i did not find a way to go through all information available and just display them, without having to write a print() statement for every field that might or might not be available in the certificate.
Does anybody have an idea how to push me into the right direction?
Its appreciated, thank you!
A solution that has actually slipped my attention is the use of the module asn1tools
import asn1tools
foo = asn1tools.compile_files("x509.asn")
output = foo.decode("Certificate", cert)
Only all ASN.1 definitions needed for X509 have to be available in the file x509.asn (available via the respective RFC), while "cert" holds the bytestring.
The result will be a python dict with all the information contained, without having to loop through anything or missing some unusual parameters

Store RSA keys in Airflow Connectors

What is the best way to store RSA connectors in Airflow Connectors?
hook = BaseHook.get_connection("my_rsa")
key = hook.extra
I am using this way. However, the key is stored as String. What is the best way to convert this to bytes?
It sounds like you're trying to secure RSA Keys... you should use airflow's crypto module
You can encrypt your keys and keep the encrypted key in an environment variable or in your own airflow.cfg
Do note that Airflow doesn't handle key rotation by default for you.
from the docs
Install crypto package pip install apache-airflow[crypto]
Generate fernet_key, using this code snippet below. fernet_key must be a base64-encoded 32-byte key:
from cryptography.fernet import Fernet
fernet_key=Fernet.generate_key()
print(fernet_key.decode()) # your fernet_key,keep it in secured place!
Replace airflow.cfg fernet_key value with the one from above. Alternatively, you can store your fernet_key in OS environment variable - You do not need to change airflow.cfg in this case as Airflow will use environment variable over the value in airflow.cfg:
#Note the double underscores
export AIRFLOW__CORE__FERNET_KEY=your_fernet_key

Google cloud storage signed url how to generate sha256 hash in python 3?

I need to use python3 and google cloud storage tgt. The example codes here is written in python2 and I am trying to change the script so it works in python3.
In python 2, SHA256 works fine.
import Crypto.Hash.SHA256 as SHA256
def _Base64Sign(self, plaintext):
"""Signs and returns a base64-encoded SHA256 digest."""
shahash = SHA256.new(plaintext)
but in python3, it doesn't seem to generate the same key.
import Crypto.Hash.SHA256 as SHA256
def _Base64Sign(self, plaintext):
"""Signs and returns a base64-encoded SHA256 digest."""
t = plaintext.encode()
shahash = SHA256.new(t)
#print(shahash)
signer = PKCS1_v1_5.new(self.key)
signature_bytes = signer.sign(shahash)
return base64.b64encode(signature_bytes)
So my question is if plaintext.encode() is changing sha256 hash or it's just pycrypto has changed for python3. What can I do to generate the same key as python 2 version? Do I have to port python2 in python 3?
Any advice would be appreciated, thanks.

How to generate a self-signed certificate for use with Network.TLS

I am writing a program to run on a single server that I control, that accepts connections from clients. The data needs to be encrypted, and server authentication is a nice touch. I'm planning to use the tls package from Hackage, as it provides both client and server encryption functionality.
I'm trying to generate a key and convert it to the X509 type, needed for the pCertificates parameter to Network.TLS. I generated the key using GnuTLS's certtool, following the directions under "Self-signed certificate generation":
certtool --generate-privkey --outfile ca-key.pem
certtool --generate-self-signed --load-privkey ca-key.pem --outfile ca-cert.pem
Here is the program I'm using to try to decode the X509 file:
import Data.ByteString (ByteString)
import Data.Certificate.PEM
import Data.Certificate.X509
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as L
decode :: ByteString -> Either String X509
decode pem =
case parsePEMCert pem of
Nothing -> Left "certificate not in PEM format"
Just certdata -> decodeCertificate $ L.fromChunks [certdata]
main :: IO ()
main = print . decode =<< B.readFile "ca-cert.pem"
It parses the PEM wrapper successfully, but does not recognize the data within:
$ ./decode
Left "certificate error: \"subject public key bad format : [OID [1,2,840,113549,1,1,1]]\""
Is this a bug in the tls package? Or am I not generating the right type of file by using the certtool commands above?
Community-wiki answer with two solutions from the comments.
1) It worked when I used GnuTLS 3.0.4 instead.
2) For future references, we worked around the issue by generating the certificate with OpenSSL toolchain, which seems to be better supported by the tls package.

Resources