I have a Smart Card (actually USB Token) with some certificate and keys written on it. Now I need to retrieve this certificate using python on Windows. How can it be achieved?
I had a look on pyscard package but it seems too low-level and probably not a most simple way of doing this. But if you know that low-level answer then your help will be appreciated.
Seems like CryptAcquireContext function from pywin32 (win32crypt) allow me to use private key from smart card for encryption purposes but I cannot get the certificate itself.
Do you have any suggestions?
Found an answer myself though. Hope it will help someone:
Usually smart card manufacturers provide a library (.so or .dll) implementing PKCS#11 standard.
There are several solutions which you can use to communicate with your smart card via this library. Such as: pkcs11-tool (CLI interface), PyKCS11 (python wrapper).
Here is an example how it could be achieved with PyKCS11:
from asn1crypto import x509
from PyKCS11 import *
pkcs11 = PyKCS11Lib()
pkcs11.load('<MANUFACTURER_LIBRARY_PATH>')
# get slot value via pkcs11.getSlotList(tokenPresent=False). Usually it's 0
session = pkcs11.openSession(slot, CKF_SERIAL_SESSION | CKF_RW_SESSION)
session.login('<SMART_CARD_PIN_CODE>')
result = []
certs = session.findObjects([(CKA_CLASS, CKO_CERTIFICATE)])
for cert in certs:
cka_value, cka_id = session.getAttributeValue(cert, [CKA_VALUE, CKA_ID])
cert_der = bytes(cka_value)
cert = x509.Certificate.load(cert_der)
result.append(cert)
print(result)
This way I was able to list certificates on smart card both on Linux and Windows
Related
I am trying to connect to RabbitMQ using Pika. We are using certificates (ssl) to do this. Here is their (Pika's) example:
context = ssl.create_default_context(
cafile="PIKA_DIR/testdata/certs/ca_certificate.pem")
context.load_cert_chain("PIKA_DIR/testdata/certs/client_certificate.pem",
"PIKA_DIR/testdata/certs/client_key.pem")
ssl_options = pika.SSLOptions(context, "localhost")
conn_params = pika.ConnectionParameters(port=5671, ssl_options=ssl_options)
This is great, if our cert files had a file path, but we are on Windows and they are stored in the windows store. So I don't believe load_cert_chain() as provided above will work.
I am able to access (or see) the specific cert like this:
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
context.load_default_certs()
certs = context.get_ca_certs()
But this gets a list of certs. I don't see any obvious way to search through and grab the cert I need. And even if I could, I am not sure how to make the code connection to "pika.SSLOptions(context,...)"
So there are two questions here, but the more important one is this:
How can I pull out a specific certificate from the windows store (since I don't have a file path)?
(the other question is how to connect this to Pika but I may be able to figure that out if the above question is answered)
Note: Pika is just a third party library that interfaces with RabbitMQ.
Note2: Using Python3.5
It looks like, after reading some hits from this search that most Python libraries that deal with the Windows cert store do so to fetch CA certs and CRL lists and not individual certs so much.
The wincertstore library might be what you're looking for.
NOTE: the RabbitMQ team monitors the rabbitmq-users mailing list and only sometimes answers questions on StackOverflow.
First things first,
SECURITY DISCLAIMER:
I'm fully aware that if I use private-encryption -> public-decryption the "encrypted" message is is readable for anyone who has access to the so called "public key".
In a normal use case of rsa this would be fatal!But in my case the "public key" is meant to be private too.
I'm trying to establish an encrypted connection where the full control stays on one party.
One of the partners is untrusted and if he would got compromised I want to be sure no one else can use the interface (to prevent privilege escalation).
As you can see in this use case encryption itself is in fact not the main reason of asymmetric "encrytion".
You actually get an encrypted data stream which can't be manipulated from a third party even if the key is leaked.
My actual communication should run between a node.js and a python environment.
The URSA node lib already has a feature for the private encryption.
Sadly pyCrypto doesn't support that for reasons mentioned above earlier.
I already tried to cheese the lib and used the private exponent to instantiate a public key object but nodejs can't decrypt the result(not a big surprise).
Does anyone know how to tackle this problem?
Is there another way to get python to do actual private key encryption?
Maybe there is another python lib capable of doing so i couldn't find?
Or maybe its possible to get the nodejs lib to decrypt my cheesie private key encryption?
I have found a working solution for me.
I simply hacked an extra method in the signing object of pyCrypto which does exactly what i want.
This works with python 2.7.9 and 3.4 as far as I tested it.
In the file "[...]/Crypto/Signature/PKCS1_v1_5.py" is the class "PKCS115_SigScheme"
I simply added following method:
def private_encrypt(self, msg):
modBits = Crypto.Util.number.size(self._key.n)
k = ceil_div(modBits,8) # Convert from bits to bytes
PS = bchr(0xFF) * (k - len(msg) - 3)
m = self._key.decrypt(b("\x00\x01") + PS + bchr(0x00) + msg)
S = bchr(0x00)*(k-len(m)) + m
return S
It's just a manipulated copy of the "sign" function.
Usage looks like:
from Crypto.Signature import PKCS1_v1_5
from Crypto.PublicKey import RSA
plain_message="Hi, I'm going to be encrypted with a private key."
key = RSA.generate(4096)
signer = PKCS1_v1_5.new(key)
bin_enc_msg = signer.private_encrypt(plain_message.encode())
The decryption after the base64 encoded transfer in nodejs with URSA publicDecrypt works fine.
It should be clear from the imports but I want to mention this nonetheless:
This actually encrypts with PKCS1.5 padded rsa.
Another solution would be to combine symmetric encryption with asymmetric signing to be able to verify it but that would require additional effort and complexity I don't want or need.
If your goal is to connect a python environment and Node.js with encryption and don't require the use of third party verification, are you required to use RSA Public key encryption? It really sounds like what you're trying to accomplish is Symmetric-key Encryption and you could use AES. The pyCrypto Library already supports this, and some googling provided this library for Node.js on git hub.
Using Python, I would like to pull data from NetSuite, along with adding/updating data in NetSuite. For example, I would like to create sales orders and add line items via Python.
I'm aware that they have a WSDL that I could potentially use. (And I was hoping that they would also have an API, but apparently not...) Does anyone have examples working with this WSDL in Python? Are there better ways to integrate with NetSuite?
I have deal with Netsuite Webservice for around one week, there is not clear documentation but once you are align with the other regular webservices behaivour is very simple adapt yourself. I attach one little script to login and to get the full list of services and data types in netsuite.
Use the factory method to create the objects to interact with the netsuite webservice.
I have used suds as SOAP Python Library.
# -*- coding: utf-8 -*-
from suds.client import Client
import os, time, sys, datetime
import suds
import logging
logging.basicConfig(level=logging.INFO)
logging.getLogger('suds.client').setLevel(logging.DEBUG)
reload(sys)
sys.setdefaultencoding('utf8')
NS_HOST = 'https://webservices.netsuite.com'
email ='myemail#xxxxxx.com'
pwd ='mypwd'
account = "99999999"
NS_ENDPOINT = "2016_2"
NS_ROLE = 3
wsdl = NS_HOST + "/wsdl/v" + NS_ENDPOINT + "_0/netsuite.wsdl"
client = Client(url=wsdl)
#You can get the methods and types with this object
print client
ApplicationInfo = client.factory.create('ns16:ApplicationInfo')
ApplicationInfo.applicationId = "xxxxx-XXXX-XXXX-XXXX-XXXXXXXX"
client.set_options(location= NS_HOST + "/services/NetSuitePort_" + NS_ENDPOINT, soapheaders={'applicationInfo':ApplicationInfo})
passport = client.factory.create('ns4:Passport')
passport.email = email
passport.password = pwd
passport.account = account
recordRef = client.factory.create('ns4:RecordRef')
recordRef.name="MX - Gerencia de Contabilidad"
passport.role = recordRef
client.service.login(passport)
Netsuite has provided toolkits for Java, .Net and PHP to access their webservices. For other languages either there are third party toolkits or you have to send Raw SOAP requests.
For my Python based projects I'm using Raw SOAP requests method. I suggest that first you get familiar with Netsuite Web services using any of the available toolkits and then for Python use this knowledge to generate raw SOAP requests. SOAPUI can also be of great help.
Have you explored restlets they are a generally good alternate for webservices.
There are a number of Python libraries available for processing SOAP messages, tried using SUDS, as it is the only one capable of properly consuming the 2014.1 Netsuite WSDL. This was only possible after some tweaks. The Netsuite WSDL is large and complex and took an enormous amount of time to load, even after caching AND loading from local. The SUDS library has not been maintained for quite a while, there is a maintained fork called SUDS-jurko that I have not yet tried. Ultimately, I ended up using raw soap messages to communicate with the Netsuite webservice for specific tasks.
I need to get the list of all puppet nodes (basically output of puppet cert list --all). What is the best way to do the same using python (without using exec or similar things on the command itself) in puppet 2.6.18
puppet 2.7.0 onwards has HTTP API to achieve the same.
http://docs.puppetlabs.com/guides/rest_api.html#certificate-request
GET /{environment}/certificate_statuses/no_key
puppetdb also one api but am not sure if the env am working with has puppetdb. (checking on that).
Is there anything like ansible.runner for puppet?
Any other thoughts?
You first need to configure access to the REST API in auth.conf. Then you can use the built-in urllib2 or external requests library to query the API with the appropriate SSL client certificate for authentication.
If you don't want to deal with SSL client certificates, you can use allow_ip in auth.conf. I'd only do that if you're not interested in the more sensitive areas of the API (like requesting a catalog).
I wrote a Python wrapper around the Puppet REST API and posted it on GitHub: pypuppet.
For example,
>>> import puppet
>>> p = puppet.Puppet()
>>> print p.certificates()
See the README and example auth.conf for more info. Let me know how it works out for you.
I'm using the suds library as a SOAP client in some project.
I would like to know if there was a way to generate Python code according to the WSDL file.
For example, consider the following line to be from the WSDL file:
<operation name="GetLastTradePrice">
Then, I want to get in some .py file the auto-generated function
def GetLastTradePrice...
The purpose of that is to be able to know what are my possible functions and properties when I have a client. That means that if I will write:
from suds.client import Client
client = Client(SOME_URL)
Then, after typing the folloewing
client.service.
I will get the option of auto-completion GetLastTradePrice.
Ye olde ZSI library can generate Python code from a WSDL definition but, compared to suds, it's quite painful to use and requires another really old module called PyXML. I'd stick to suds, auto-completion isn't worth all that.
There are many SOAP server implementations for python, some more usable than others, search for packages related to SOAP at PyPI or take a look at the wiki page about web services at python.org. There are essentially two types of SOAP servers for python:
Servers that can generate server stubs from WSDL files (like ZSI)
Servers that can produce WSDL from the service class methods directly (like soaplib, ladon)