Validate valid certificate with attribute PSEUDONYM - java

At the moment I'm receiving messages which are signed with a certificate.
So far so good.
However the certificate contains an attribute PSEUDONYM.
Now the Java runtime doesn't accept it. I get an IO Exception. (When I remove the PSEUDONYM exception is gone )
Does anybody know you to validate these messages as i'm sure that attribute PSEUDONYM is allowed.
C=DE,O=InfoCompany,OU=SoftwareMe,CN=SIGNER,SERIALNUMBER=1,PSEUDONYM=SIGNER
Any ideas how to change the default java validation to allow the PSEUDONYM tag?

Using constructor X500Principal(String name, Map<String,String> keywordMap) allows you to specify custom RDNs in keywordMap. The map's key is a RDN name and the value is a string representation of OID. See Java documentation for details.

Related

How to use key marker in ListObjectVersions, AWS S3 Java SDK

I am working on a task to delete all the PDF document versions given their document key(Unique for each PDF) using AWS Java SDK.
Other developers have integrated the download code like below
final GetObjectRequest request = GetObjectRequest.builder().bucket(bucketName).key(documentKey).versionId(version).build();
return client.getObject(request);
After searching a bit I found this code to delete single version :-
DeleteObjectRequest request = DeleteObjectRequest.builder().bucket(bucketName)
.key(documentKey).versionId(version).build();
DeleteObjectResponse resp = client.deleteObject(request);
Main question :- How do I get all versions of single documentKey ?
I found ListObjectVersions on
below URL but It accepts a key-marker and not the actual key
key-marker Specifies the key to start with when listing objects in a
bucket.
https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectVersions.html
I am just worried if I don't use this properly I might end up deleting something else in Prod.
Edit :- All the PDFs are stored at root level in S3 bucket.
The documentation states:
key-marker
Specifies the key to start with when listing objects in a bucket.
This means by specifying key-marker, you're just starting listing objects at the specified key. ListObjectVersions can and will continue listing objects past the specified key.
Further in the documentation:
prefix
Use this parameter to select only those keys that begin with the specified prefix.
In other words, if you pass a prefix of only the object name, it will return the versions for that object, along with all objects that start with that prefix.
So, you can specify either the prefix of the target object key, or the key marker, but you will need still need to filter in either event to ensure you don't include other objects.

Send Encryption Password To LDAP in Java

I have a problem and I have no idea how to solve it.
I load an encrypted password (SSHA) from a text file and I need add a user with this password from the source code in Java.
Example from file:
e1NTSEF9Ukd6ZEZyanZBZlJGMGs3eGFDOGZxQ3U3QlozcUZXRGJoeWIyS0E9PQ==
Real password: 123
Example code not work as I want:
String encryptedPSWD = "e1NTSEF9Ukd6ZEZyanZBZlJGMGs3eGFDOGZxQ3U3QlozcUZXRGJoeWIyS0E9PQ==";
attributes.add(new BasicAttribute("userPassword","{SSHA}"+encryptedPSWD);
It not work, because we can send only real value password?
And is the problem that this is one-sided encryption and LDAP will also not be able to decrypt it?
The error number and text from the LDAP server would be instructive; but, in a general case, there are two things that stand out:
(1) Assuming the user already has a password, you are modifying an existing attribute, not adding an attribute. If you attempt to add a value to a single valued attribute that's already got a value, or if you attempt to add a value to a multi-value attribute that is already present, you would get ldap error 20. To modify an existing attribute would look something like this:
LDAPModificationSet attributes = new LDAPModificationSet();
LDAPAttribute attrUserPassword = new LDAPAttribute("userPassword", "{SSHA}"+encryptedPSWD);
attributes.add(LDAPModification.REPLACE, attrUserPassword);
(2) Some directories do not allow using "pre-encoded" passwords as a default. This is because password policies cannot be applied to an unknown password (i.e. how do I know this password is at least eight characters, contains a special character, and does not contain a dictionary word?). The Oracle Unified Directory servers that I manage return error 53 in this case, along with text saying "Pre-encoded passwords are not allowed for the password attribute userPassword.", but other directory servers may return use a different code (53 is a pretty generic code that just means something in the server config prevented the action from being completed). How to sort it depends on the LDAP server -- mine have a allow-pre-encoded-passwords Boolean within the password policy. I generally set it to "true", bulk import users, then return the setting to 'false' to prevent app developers from circumventing our password policies.

Clarify RSA SAML Response

Is not so clear to me how to check and parse value passed by this partial response envelope in SAML 2.0:
<dsig:Signature xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
<dsig:SignedInfo><dsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#WithComments"/><dsig:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<dsig:Reference URI="#ID_ce8c62aa-08e4-4a21-a89a-af4fbd7a9f50">
<dsig:Transforms><dsig:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</dsig:Transforms><dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<dsig:DigestValue>ImUVGjTf7WTCmboAbAtjx7WKQhI=</dsig:DigestValue>
</dsig:Reference>
</dsig:SignedInfo>
<dsig:SignatureValue>CDk+O/3PPh57l84pjFW0xwiPYJ+yinYJciBowT3nkPaAXeMYCH1AopZl7ZP+swPiK+oYuW9STPSlJVuEuDao5VbSU2WlQR7Ed9nZMt9PNY19/eKtkAqbMk01ZY8YH6OyTQm17w6IzNRbY4sJcHSRz9eDUsTzAYVhV9PEBgT1ouZsghklMCe0iYBjK5LmRS88jGmCN5sZ5+L8+KimTCakWSJ8CLntEAFx1SBL50Or4e8j6nHiW7g==</dsig:SignatureValue>
<dsig:KeyInfo>
<dsig:KeyValue>
<dsig:RSAKeyValue>
<dsig:Modulus>4Gvzu2dCYGhdWr9Er/WtgbWRqAR798IPCfAubx8NeBKG/X6P7sM91zbD2LEH4tJS2vkMCnQFidoLdeh1SHp7+GLHnVsgTcj6NPOit0EOHz10tdRmFMwoRCh5hcMFEisFUgSdaS8bO2wSXBmLENfLDUOSYKKLP0JGtTqnAZ0A99UNrVWKemx/EnHopH+Q7M+zmbj8VWFVlCK6rDfXJLUBr+kGSlw==</dsig:Modulus>
<dsig:Exponent>AQAB</dsig:Exponent>
</dsig:RSAKeyValue>
</dsig:KeyValue>
</dsig:KeyInfo>
</dsig:Signature>
So basically the RSAKeyValue should contain the "public key" to read the DigestedValue?
So what's the purpose of the Signature value?
I would like to implement a Java class to decrypt (I have the proper keystore and pass to do that...). Please point me in the right direction.
As written in the comment, it's an XML signature. The signature allows you to validate the XML has been signed by a trusted party and the element hasn't been modified. So you can trust the SAML response is really from the IdP you can trust. It is not encryption.
I would like to implement a Java class to decrypt
As I stated there's nothing to decrypt, you can only validate integrity of the signed XML element.
For that I suggest you use an out of box library to process the XML (it will be boring to implement all canonization options, etc..). I suggest you use an out of box library ( OpenSAML, spring-security-saml2) to validate the signature.
if you want to do it yourself, just read search/about the XML signatures.
What you have there:
<dsig:Reference URI="#ID_ce8c62aa-08e4-4a21-a89a-af4fbd7a9f50">
There must be an element in your XML with id attribute of "#ID_ce8c62aa-08e4-4a21-a89a-af4fbd7a9f50" and the signature ensures integrity of the refered XML element. Make sure the signature is refered to the whole SAML message or an assertion element. If not, you're code would be prone to signature injection attacks. That's why I suggest you use a mature library for that.
<dsig:DigestValue>ImUVGjTf7WTCmboAbAtjx7WKQhI=</dsig:DigestValue>
RSA doesn't work with messages of arbitrary (any) length, so a message digest (sha-1 hash) is created and that is signed. The DigestValue is value of the hash created from the signed XML element and its content. (how to create a whole content to be hashed is depending on the parameters stated in the CanonicalizationMethod, Transforms, DigestMethod, you can read about it in the first link)
<dsig:SignatureValue>
This is the RSA/PKCS1.5 signature of the DigestValue
I hope that clarifies your question.

Generating a PKCS10 Certificate request with extra fields in java

I need to add extra fields in the CSR, like keyusage, regestrationID etc.I am using java IBM-sdk60. I've gone through x500 name API's and could not find any solution. Help on API's would be appreciated.
Thanks in advance
The standard way to include additional information in a CSR (PKCS#10) request is by adding Attributes. According to the PKCS#10 standard:
The intention of including a set of attributes is twofold: to provide
other information about a given entity , or a "challenge password" by
which the entity may later request certificate revocation; and to
provide attributes for inclusion in X.509 certificates. A
non-exhaustive list of attributes is given in PKCS #9
An attribute is an OID and a value whose meaning depends on the OID
Actually PKCS#9 defines 3 attributes:
Challenge password
Extension request
Extended-certificate attributes (this is deprecated)
The one you are looking for is Extension request :
The extensionRequest attribute type may be used to carry information
about certificate extensions the requester wishes to be included in a
certificate.
This code template (not tested) may give you some hints on how include this attribute
CertificateExtensions exts = /* build the extensions set you want to include */
/* Wrap the extensions set into a SET OF */
OutputStream out = new ByteArrayOutputStream();
exts.encode(out);
DerValue val = new DerValue(DerValue.tag_SetOf, out.toByteArray());
PKCSAttribute extReq = new PKCSAttribute(new ObjectIdentifier("1.2.840.113549.1.9.14"), val.toByteArray());
PKCSAttributes attrs = new PKCSAttributes(new PKCSAttribute[] { extReq });
CertificationRequestInfo cri = new CertificationRequestInfo(subject, key, attrs);
CertificationRequest csr = new CertificationRequest(cri);
Please note that unless the CA explicitly announces this PKCS#10 attribute is supported it will be ignored during the certificate generation.

Loading a keystore without checking its integrity

This question is in the specific context of the Java class java.security.KeyStore and its load(InputStream stream, char[] password) method which can accept null values for password to bypass integrity checking.
What are the risks involved with loading and querying a keystore without checking its integrity? The keystore will be queried for the user's private key which will be used to sign a document for non-repudiation. The certificate queried will be further validated against a copy stored in a database at the time the user registered himself and the (supposedly exact same) cert.
Well the main risk is that anyone who can read the file can also modify it. So someone could replace the file you read with a different keystore that has the same names for the keys but contains a different private key, so you end up signing documents with the wrong private key and none of them will pass verification.
Also, anyone with access to the file gains access to the private key and can sign documents as if they came from your app.

Categories