Keystore from digital signature e-token using java - digital-signature

How to create the keystore from digital signature e-token? How crate the path of keystore? How to sign with the keystore in any document using java application?

Cryptographic hardware devices can usually be interfaced via PKCS#11 API. You will need PKCS#11 library (.dll on Windows or .so on Unix) acting as a "device driver" which gets usually installed along with the software provided by the device vendor (consult your e-token documentation for the exact library location). You have mentioned "keystore" in your question therefore I guess you are using JAVA language and you can use SunPKCS11 provider to access PKCS#11 compatible cryptographic store. Here is the quick sample:
// Create instance of SunPKCS11 provider
String pkcs11Config = "name=eToken\nlibrary=C:\\path\\to\\your\\pkcs11.dll";
java.io.ByteArrayInputStream pkcs11ConfigStream = new java.io.ByteArrayInputStream(pkcs11Config.getBytes());
sun.security.pkcs11.SunPKCS11 providerPKCS11 = new sun.security.pkcs11.SunPKCS11(pkcs11ConfigStream);
java.security.Security.addProvider(providerPKCS11);
// Get provider KeyStore and login with PIN
String pin = "11111111";
java.security.KeyStore keyStore = java.security.KeyStore.getInstance("PKCS11", providerPKCS11);
keyStore.load(null, pin.toCharArray());
// Enumerate items (certificates and private keys) in the KeyStore
java.util.Enumeration<String> aliases = keyStore.aliases();
while (aliases.hasMoreElements()) {
String alias = aliases.nextElement();
System.out.println(alias);
}

Related

UWP on RPi - Trying to Provision to Azure - How to get X.509 certificate

I'm working with a RPi/UWP program (works well) that is signed with out X.509 certificate.
I have no problems connecting to Azure IoT hub if I manually provision the connection, but as we intend to ship these by the 100s, if not thousands, obviously that won't work.
I've looked at the code examples of using the provisioning service, but all of them are in the emulation.
Looking at the code, you have to load your X.509 certificate
certificateCollection.Import(s_certificateFileName, certificatePassword, X509KeyStorageFlags.UserKeySet);
This is where I get lost - Where on the RPi IS the certificate to load?
Basically, I THINK I understand how to do this in a plain Win10 app, but when you get to UWP on the RPi (a 3B, as the 3B+ is not supported - probably have to switch to Core) . Anyone have some sample code, or can point me in the right direction?
This document provides an overview of the cryptography features available to UWP apps.
You can generate the certificate file and then copy or import it to the device. If you copy the certificate file to device, you need to add capabilities for accessing the file to your UWP app. Please refer to this topic in MSDN forum. Following code can be used to import the pfx certificate into your device and then load it from cert store.
Import:
StorageFolder certificatesFolder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync("Certificates");
StorageFile certificateFile = await certificatesFolder.GetFileAsync("ClientCertificate .pfx ");
IBuffer certificateBuffer = await FileIO.ReadBufferAsync(certificateFile);
string encodedCertificate = Windows.Security.Cryptography.CryptographicBuffer.EncodeToBase64String(certificateBuffer);
await CertificateEnrollmentManager.ImportPfxDataAsync(encodedCertificate, "password", ExportOption.NotExportable, KeyProtectionLevel.NoConsent, InstallOptions.None, "certificateOne");
Load:
CertificateQuery certQuery = new CertificateQuery();
certQuery.FriendlyName = "certificateOne";
IReadOnlyList<Certificate> certificates = await CertificateStores.FindAllAsync(certQuery);

Storing encrypted PrivateKey's to Java Keystores

Java Keystores (e.g. JKS, PKCS) allow saving private keys (interface
Key) and
certificate chains. However a RSA KeyPair's private key which is encrypted
(e.g. EncryptedPrivateKeyInfo in bouncycastle or in javax) does not implement
Key interface.
What is the correct way to store encrypted private keys in a keystore?
If you already have an EncryptedPrivateKeyInfo, you should be able to use that directly when creating the keystore entry. Java stores the PrivateKey in the KeyStore as EncryptedPrivateKeyInfo format.
You need to use this method in the KeyStore.setKeyEntry(String alias, byte[] key, Certificate[] chain). Documentation here.
The other setKeyEntry method takes in an addtional argument, which is the password, which the Java will construct the EncryptedPrivateKeyInfo itself with the password provided.
Note: Only if the Key Protection Algorithm is supported by Java, it will import the private key, or else it will complain. If it does complain, you can look at other option of decrypting the encrypted private key yourself, and using the other setKeyEntry() method.

Google Calendar API and shared hosting issue

I'm trying to use a public Google calendar in a webpage that will need editing functionalities.
To that effect, I created the calendar and made it public. I then created a Google service account and the related client id.
I also enabled the Calendar API and added the v3 dlls to the project.
I downloaded the p12 certificate and that's when the problems start.
The call to Google goes with a X509 cert but the way the .NET framework is built is that it uses a user temp folder.
Since it's a shared host for the web server (GoDaddy), I cannot have the app pool identity modified.
As a result, I'm getting this error:
System.Security.Cryptography.CryptographicException: The system cannot
find the file specified.
when calling:
X509Certificate2 certificate = new X509Certificate2(GoogleOAuth2CertificatePath,
"notasecret", X509KeyStorageFlags.Exportable);
that cerificate var is then to be used in the google call:
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(GoogleOAuth2EmailAddress)
{
User = GoogleAccount,
Scopes = new[] { CalendarService.Scope.Calendar }
}.FromCertificate(certificate));
... but I never get that far.
Question: is there a way to make the call differently, i.e. not to use a X509 certificate but JSON instead?
Or can I get the x509 function to use a general temp location rather than a user location to which I have no access to since I can't change the identity in the app pool?
Since I'm completely stuck, any help would be appreciated.
One simple option which avoids needing to worry about file locations is to embed the certificate within your assembly. In Visual Studio, right-click on the file and show its properties. Under Build Action, pick "Embedded resource".
You should then be able to load the data with something like this:
// In a helper class somewhere...
private static byte[] LoadResourceContent(Type type, string resourceName)
{
string fullName = type.Namespace + "." + resourceName;
using (var stream = type.Assembly.GetManifestResourceStream(fullName)
{
var output = new MemoryStream();
stream.CopyTo(output);
return output.ToArray();
}
}
Then:
byte[] data = ResourceHelper.LoadResourceContent(typeof(MyType), "Certificate.p12");
var certificate = new X509Certificate2(data, "notasecret", X509KeyStorageFlags.Exportable);
Here MyType is some type which is in the same folder as your resource.
Note that there are lots of different "web" project types in .NET... depending on the exact project type you're using, you may need to tweak this.

How to add custom certificate authority (CA) to nodejs

I'm using a CLI tool to build hybrid mobile apps which has a cool upload feature so I can test the app on a device without going through the app store (it's ionic-cli). However, in my company like so many other companies TLS requests are re-signed with the company's own custom CA certificate which I have on my machine in the keychain (OS X). However, nodejs does not use the keychain to get its list of CA's to trust. I don't control the ionic-cli app so I can't simply pass in a { ca: } property to the https module. I could also see this being a problem for any node app which I do not control. Is it possible to tell nodejs to trust a CA?
I wasn't sure if this belonged in Information Security or any of the other exchanges...
Node.js 7.3.0 (and the LTS versions 6.10.0 and 4.8.0) added NODE_EXTRA_CA_CERTS environment variable for you to pass the CA certificate file. It will be safer than disabling certificate verification using NODE_TLS_REJECT_UNAUTHORIZED.
$ export NODE_EXTRA_CA_CERTS=[your CA certificate file path]
You can specify a command line option to tell node to use the system CA store:
node --use-openssl-ca
Alternatively this can be specified as an environment variable, if you are not running the node CLI directly yourself:
NODE_OPTIONS=--use-openssl-ca
There is an undocumented, seemingly stable, API for appending a certificate to the default list:
const tls = require('tls');
const secureContext = tls.createSecureContext();
// https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem.txt
secureContext.context.addCACert(`-----BEGIN CERTIFICATE-----
MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow
SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT
GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF
q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8
SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0
Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA
a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj
/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T
AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG
CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv
bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k
c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw
VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC
ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz
MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu
Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF
AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo
uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/
wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu
X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG
PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6
KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==
-----END CERTIFICATE-----`);
const sock = tls.connect(443, 'host', { secureContext });
For more information, checkout the open issue on the subject: https://github.com/nodejs/node/issues/27079
I'm aware of two npm modules that handle this problem when you control the app:
https://github.com/fujifish/syswide-cas (I'm the author of this one)
https://github.com/coolaj86/node-ssl-root-cas
node-ssl-root-cas bundles it's own copies of nodes root CAs and also enables adding your own CAs to trust. It places the certs on the https global agent, so it will only be used for https module, not pure tls connections. Also, you will need extra steps if you use a custom Agent instead of the global agent.
syswide-cas loads certificates from pre-defined directories (such as /etc/ssl/certs) and uses node internal API to add them to the trusted list of CAs in conjunction to the bundled root CAs. There is no need to use the ca option since it makes the change globally which affects all later TLS calls automatically.
It's also possible to add CAs from other directories/files if needed.
It was verified to work with node 0.10, node 5 and node 6.
Since you do not control the app you can create a wrapper script to enable syswide-cas (or node-ssl-root-cas) and then require the ionic-cli script:
require('syswide-cas'); // this adds your custom CAs in addition to bundled CAs
require('./path/to/real/script'); // this runs the actual script
This answer is more focused towards package maintainers/builders.
One can use this method if you do not want end users to rely on additional environment variables.
When nodejs is built from source, it (by default, can be overridden) embeds the Mozilla CA certificate database into the binary itself. One can add more certificates to this database using the following commands:
# Convert your PEM certificate to DER
openssl x509 -in /path/to/your/CA.pem -outform der -out CA.der
# Add converted certificate to certdata
nss-addbuiltin -n "MyCompany-CA" -t "CT,C,C" < CA.der >> tools/certdata.txt
# Regenerate src/node_root_certs.h header file
perl tools/mk-ca-bundle.pl
# Finally, compile
make install

Jasypt StandardPBEStringEncryptor setting password in spring bean configuration file

When using Jasypt's StandardPBEStringEncryptor we have to set password explicitly in spring bean configuration file. Is it ok and secure to have the password in the bean configuration file? Will it be a problem in PCI Compliance to store the encryptor password?
This will not be PCI compliant. Data encrypting keys cannot be stored in plaintext. The specific point is 3.5.2 which is:
Examine system configuration files to
verify that keys are stored in
encrypted format, and that
key-encrypting keys are stored
separately from data-encrypting keys.
You would probably also have other issues around the key management area, such as 3.6.6 (Split knowledge and dual control of keys)
Verify that key-management procedures
are implemented to require split
knowledge and dual control of keys
(for example, requiring two or three
people, each knowing only their own
part of the key, to reconstruct the
whole key).
Key management is the most challenging part of PCI compliance. You may want to consider using a (already PCI compliant) 3rd party to manage your card data. If you are rolling your own then I would advise that you bring in the assistance of a QSA (PCI Qualified Security Assesor) at the earliest opportunity to evaluate the security you're planning on implementing. ultimately it will be the QSA that you need to convince in order to pass your PCI requirements, and they will be more than happy to advise.
You need to store the symmetric key somewhere. A configuration file is a good place, as long as no one has access to it.
I have an idea
you can encrypt all of your plain password with keyPair of keystore.jks. You know that the keystore.jks has its own password. you can remember that password and when your program get started enter it on console. for example when your program start:
Console console = System.console();
keyPair = loadKeystore(new String(console.readPassword()));
private static KeyPair loadKeystore(String pwd) {
InputStream is = Main.class.getResourceAsStream("/keystore.jks");
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
keystore.load(is, s.toCharArray());
String alias = "youralias";
Key key = keystore.getKey(alias, pwd.toCharArray());
if (key instanceof PrivateKey) {
// Get certificate of public key
Certificate cert = keystore.getCertificate(alias);
// Get public key
PublicKey publicKey = cert.getPublicKey();
// Return a key pair
return new KeyPair(publicKey, (PrivateKey) key);
}
return null;
}
when you return the keypair you can uses it for encrypt your password.
key = loadKeystore("yourpass").getPrivate().getEncoded()
goodluck

Resources