Full code below.
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography import x509
from cryptography.x509.oid import NameOID
from cryptography.hazmat.primitives import hashes
import datetime
encryptedpassword = b"yokedicicaner31" #Kullanıcı inputu al, yokedicicaner31, kopyala yapıştır.
key = rsa.generate_private_key(public_exponent=65537,key_size=2048,backend=default_backend())
with open("rsakey.pem","wb") as f:
f.write(key.private_bytes(encoding=serialization.Encoding.PEM,
format = serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.BestAvailableEncryption(encryptedpassword)))
subject = issuer = x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME,u"TR"),
x509.NameAttribute(NameOID.LOCALITY_NAME,u"damacaner"),
x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"damacana ve erikli su sevenler derneği"),
x509.NameAttribute(NameOID.COMMON_NAME, u"damacaner.tr")])
cert = x509.CertificateBuilder().subject_name(subject).issuer_name(issuer).public_key(key.public_key()).serial_number(x509.random_serial_number()).not_valid_before(datetime.datetime.utcnow()).not_valid_after(datetime.datetime.utcnow() + datetime.timedelta(days=10)
).add_extension(x509.SubjectAlternativeName([x509.DNSName(u"localhost")]),critical=False).sign(key, hashes.SHA256(), default_backend())
with open("certificate.pem","wb") as f:
f.write(cert.public_bytes(serialization.Encoding.PEM))
Full output below.
unable to load X509 request
34359836736:error:0909006C:PEM routines:get_name:no start line:crypto/pem/pem_lib.c:745:
Expecting: CERTIFICATE REQUEST
I tried to open the certificate file called certificate.pem with "openssl req -text -in certificate.pem" commands but it shooted the error that I wrote at output. This error didnt happen when I built certificate with x509.CertificateSigningRequestBuilder but I get an error when I try to build a self-signed certificate with x509.CertificateBuilder. Thanks for all help.
Check if the first line of your certificate request starts with:
-----BEGIN CERTIFICATE REQUEST-----
It is unclear what you are trying to do here, since you only describe the problems you run into and not what task you are trying to implement at the end. Anyway ...
openssl req -text -in certificate.pem
This line expects a certificate request. Your code instead creates a certificate (CertificateBuilder), not a certificate request. The latter would be created with x509.CertificateSigningRequestBuilder, which as expected works with the openssl req command above.
... I get an error when I try to build a self-signed certificate with x509.CertificateBuilder.
It does not look like you get an error when building the self-signed certificate, i.e. the code to build the certificate works. Instead you get an error when using it with openssl req. This error is expected since you did not provide a certificate request but instead a certificate. For certificates use the x509 openssl command not req:
openssl x509 -text -in certificate.pem
Related
I'm using python to access Aruba switches through an API. I'm wanting to use HTTPS so that my traffic (that is sending usernames and passwords for verification) is encrypted:
import requests
import json
import base64
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
import certifi
url = 'https://10.4.10.10/rest/v3/'
creds = {'userName': 'username', 'password': 'password'}
command = 'show config'
s = requests.Session()
r = s.post(url + 'login-sessions', data=json.dumps(creds), timeout=1)
print(r.json())
cookie_response = r.json()['cookie']
if r.status_code != 201:
print('Login error, status code {}'.format(r.status_code))
I generated a self signed certificate in the CLI and then was able to grab it by putting the ip address into chrome (with https:// in front of it) and then downloading the certificate file. I had to use openssl to convert the certificate file type into a .pem. Finally, I opened the file in a text editor and added the certificate to the end of the cacert.pem file that is used by the Requests module. After doing all this, I still get the following error:
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1076)
I've searched all over, but still can't find a solution. Any help or ideas would be greatly appreciated! Thanks!
-EDIT-
Here is the contents of the certificate I am using:
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
17:13:91:1c:86:72:ae:bd:01:27:28:39:8f:4e:5a:2d:18:ae:1f:04
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=testSwitch, OU=OCSwitch, O=OC, L=Edmond, ST=Oklahoma, C=US
Validity
Not Before: Jun 16 10:59:12 2020 GMT
Not After : Jun 16 23:59:59 2021 GMT
Subject: CN=testSwitch, OU=OCSwitch, O=OC, L=Edmond, ST=Oklahoma, C=US
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (1024 bit)
Modulus (1024 bit):
00:be:6a:27:02:f5:6a:98:19:0f:db:c7:11:26:dd:
77:26:bd:18:ef:ab:62:53:3e:13:a1:61:b0:5a:88:
77:d8:ba:81:56:2a:7d:66:0a:2c:cd:f1:78:4b:35:
61:73:31:4c:4f:80:51:21:86:bf:2c:1c:95:87:cc:
e7:5f:47:d8:d8:6e:ed:d4:4f:56:79:24:01:65:c9:
72:cb:6c:7a:55:ef:9b:1b:ae:4e:28:8f:27:50:1d:
36:08:c3:85:67:2c:8a:1a:42:15:83:d2:e3:b3:ef:
d3:ce:cd:77:d5:3f:25:f5:b3:c1:ce:e8:7c:e1:cb:
fc:c5:12:e8:0a:d0:87:1b:4d
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment, Key Agreement
X509v3 Extended Key Usage:
TLS Web Server Authentication
Signature Algorithm: sha256WithRSAEncryption
51:01:6c:13:40:8a:73:70:96:71:ea:b1:4b:b1:36:c3:82:ed:
2b:3a:d8:b3:23:77:6e:bb:56:d5:71:56:ff:0a:66:4f:81:69:
ef:33:9e:1f:ff:20:3e:49:70:c4:8b:c9:92:65:ce:80:78:62:
0e:e4:8e:39:ee:e0:04:6d:73:67:41:1a:dd:1e:ec:19:af:45:
0b:f3:4b:2e:88:10:5e:c1:89:6b:37:d1:12:a7:23:e1:86:94:
4f:b2:8a:fd:62:d6:33:5f:14:62:50:2e:38:0f:b1:46:55:ad:
46:71:df:b3:6d:44:48:c9:72:f5:0b:0a:13:ed:9a:2f:05:5c:
05:0b
I've modified my code by importing ssl and using ssl.get_server_certificate():
import ssl
cert = ssl.get_server_certificate(('10.4.10.10', 443))
with open('cert.pem', 'w') as file:
file.write(cert)
I then point to 'cert.pem' with verify= and still get the same error.
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment, Key Agreement
X509v3 Extended Key Usage:
TLS Web Server Authentication
This is a leaf certificate and not a CA certificate (no basic constraints CA:true). OpenSSL historically requires the trust anchor for verification to be a self-signed CA certificate though.
This is changed only with newer versions (OpenSSL 1.0.2 and later) when the option X509_V_FLAG_PARTIAL_CHAIN is used in certificate verification. In this case an arbitrary CA certificate in the CA store would work as trust anchor and also self-signed certificates without CA:true seem to work.
Unfortunately this flag is not exposed in Python yet and I see no way to specify custom verify options or a custom context with special verify options to requests. With other libraries this might be more doable, see Python WWS Library requires entire certificate chain to verify server.
Could you check if the certificates were imported from the root level to the bottom of the chain? Also, try to pass the path to the certificate file in the requests function to see if the certificate works:
r = s.post(url, data=data, verify='/path/to/public_key.pem')
I am trying to send https request to IIS server using python request and fetch the response for parsing.Authentication is done using self signed certificates.I have generated certificate with password and key by using following commands. I am using TestPublicKey.pem and plainkey.pem as inputs to cert attribute in requests.get method. Can someone guide me how to achieve this ?
C:\OpenSSL-Win64\bin>openssl req -x509 -newkey rsa:2048 -keyout TestPrivateKey.pem -out TestPublicKey.pem -days 9999
C:\OpenSSL-Win64\bin>openssl pkcs12 -inkey TestPrivateKey.pem -in TestPublicKey.pem -export -out Test.pfx
Enter pass phrase for cTestPrivateKey.pem:
Enter Export Password:
Verifying - Enter Export Password:
C:\OpenSSL-Win64\bin>openssl rsa -in TestPrivateKey.pem -out plainkey.pem
Enter pass phrase for TestPrivateKey.pem:
writing RSA key
import requests
url = "https://10.110.20.75/REST/getxml"
r = requests.request("GET", url, verify=False,cert=('TestPublicKey.pem','plainkey.pem'))
print r.status_code
if verify is set to False , then getting 403 status_code. If verify is set to True then SSL Error exception is raised.
raise SSLError(e, request=request)
requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:661)
I got this resolved by trying with following openssl commands and python code.
Note: This answer is certificate without password, if any answers or comments.I am glad to see.
Open SSL commands
Generate the self signed certificate
openssl req -x509 -nodes -days 30 -newkey rsa:2048 -keyout test_Private.key -out test_certificate.cer -subj "/CN=*.hpe.com"
Convert certificate and private key to .PFX
openssl pkcs12 -export -out test_PFX.pfx -inkey test_Private.key -in test_certificate.cer -name "*.hpe.com" -passout pass:
Python code
import requests
url = "https://10.110.20.75/REST/getxml"
webServiceResponse=requests.request("GET",url,verify='test_certificate.cer)
print webServiceResponse.status_code
print webServiceResponse.json()
I'm developing 'APNS function' with Django.
This is my code to send push notification to the ios device
PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
apns = APNs(use_sandbox=True, cert_file=PATH+'/app/certificate.pem')
token_hex = 'UUID from ios Device'
payload = Payload(alert="Hello World!", sound="default", badge=1)
apns.gateway_server.send_notification(token_hex, payload)
return Response({'test'})
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 522, in init
self._context.load_cert_chain(certfile, keyfile)
SSLError: [SSL] PEM lib (_ssl.c:2580)
Yes, I already did search for the same issue and I'm almost sure that my 'certificate.pem' file is correct.
But one of my guessing things, I didn't insert the password for that 'certificate.pem' file.
Is it the reason for that error?
If so , where should I put the password for it?
Anyone solving this error?
'SSLError: [SSL] PEM lib'
It was because of 'certifcate.pem' file. I had misunderstood how to create the correct 'certificate.pem' file. I did follow the instruction from 'http://www.apptuitions.com/generate-pem-file-for-push-notification/'.
Then, I could make the difference although I have not succeeded in pushing and receiving notifications.
I wish this is helpful for those having the same error messages
I got .cer, .p12 and .pem from Apple.
What worked for me was:
openssl x509 -inform der -in aps_development.cer -out cert.pem
openssl pkcs12 -in private.p12 -out key.pem -nocerts
cat key.pem cert.pem > dev.pem
I haven't used the .pem from Apple. The method from the website ( http://www.apptuitions.com/generate-pem-file-for-push-notification/ ) did not work for some reason.
Say that I have a cer file called symantec-class3.cer, this is what I'm trying:
headers = {"content-type": "application/json"}
api_url = "https://www.someurl.com/search"
pprint.pprint(requests.post(api_url, auth=HTTPBasicAuth(username, password), verify="symantec-class3.cer", data=json.dumps(payload), headers=headers).json())
This is not liking it and spews out the following error:
requests.exceptions.SSLError: [Errno 0] _ssl.c:344: error:00000000:lib(0):func(0):reason(0)
It works fine if I turn verify False, but I'm trying to use a cert file in my local directory.
Python expect cert in PEM format.
So you should extract the public key component from the X509 certificate using the openssl x509 command.
.cer extension often means a binary DER format, so this command should extract the public key in a form that can be used by pycrypto:
openssl x509 -inform der -pubkey -noout -in you.cer >public_key.pem
I have a .cer file containing public key. I need to use this file to verify signature signed by corresponding private key.
I have the signature and public key. I need to verify the signature.
I'm getting result as false.
Below is the code:
def verify_sign(public_key_loc, signature, data):
'''
Verifies with a public key from whom the data came that it was indeed
signed by their private key
param: public_key_loc Path to public key
param: signature String signature to be verified
return: Boolean. True if the signature is valid; False otherwise.
'''
#pdb.set_trace()
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA256
from base64 import b64decode
try:
pub_key = open(public_key_loc, "r").read()
rsakey = RSA.importKey(pub_key)
signer = PKCS1_v1_5.new(rsakey)
digest = SHA256.new()
# Assumes the data is base64 encoded to begin with
digest.update(b64decode(data))
if signer.verify(digest, b64decode(signature)):
return True
return False
except Exception as e:
print e
I tried to use method here to convert .cer file to .pem. How do I use a X509 certificate with PyCrypto?
Is the method used here is correct? or does python has better libraries. Because as far as i know, python does not support X.509Certificate.
Bear my english.
Appreciate any help.
Thanks.
Edit:
As of now, i'm trying to use Pycrypto.
Do i need to use any other libraries or method in the same pycrypto?
You should be able to extract the public key component from the X509 certificate using the openssl x509 command. You say that your certificate file has a .cer extension which often means a binary DER format, so this command should extract the public key in a form that can be used by pycrypto:
openssl x509 -inform der -pubkey -noout -in certificate.cer >public_key.pem
Although, it's possible that your .cer file is already in PEM format (I suspect that it is because in C# you needed to base64 decode this certificate), in which case this command should get the public key:
openssl x509 -pubkey -noout -in certificate.cer >public_key.pem
Either way you should end up with a file public_key.pem that resembles this PEM format key:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq8ZtNvMVc3iDc850hdWu
7LLw4CQfE4O4IKy7mv6Iu6uhHQsfRQCqSbc1Nwxq70dMudG+41cSBI2Sx7bsAby2
2seBOCCtcoXmDvyBbAetaHY4xUTXzMZKxZc+ZPRR5vB+suxW9yWCTUmYyxaY3SPx
iZHRF5dAmSbW4qIrXt+9ifIbGlMtzFBBetA9KgxVcBQB6VhJEHoLk4KL4R7tOoAQ
gs6WijTwzNfTubRQh1VUCbidQihVAOWMNVS/3SWRRrcN5V2DqOWL+4TkPK522sRD
K1t0C/i+XWjxeFu1zn3xXZlA2sruOIFQvpihbLgkrfOvjA/XESgshBhMfbXZjzC1
GwIDAQAB
-----END PUBLIC KEY-----
Now you can load this using Crypto.PublicKey.RSA.importKey().
You also should double check the encoding of data and signature; make sure that these are base64 encoded as you assume, although this is probably correct since you have it working in C#.
Other options exist:
Use good old pyOpenSSL - see module OpenSSL.crypto:
import OpenSSL
cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_ASN1,
open('certificate.cer').read())
try:
OpenSSL.crypto.verify(cert, signature, data, 'sha256')
print "Signature verified OK"
except Exception as e:
print "Signature verification failed: {}".format(e)
Use M2Crypto (Python 3 not supported):
import M2Crypto
cert = M2Crypto.X509.load_cert('certificate.cer', M2Crypto.X509.FORMAT_DER)
pubkey = cert.get_pubkey()
pubkey.reset_context('sha256')
pubkey.verify_init()
pubkey.verify_update(content)
verified = pubkey.verify_final(signature)