I have a x509 certificate (PEM format) and I want to load it in Go so that I can extract the public key and the signature from it. Extracting the signature works fine, but when extracting the public key I get some padding + the public key.
Does anyone know why that padding is added and how I can remove it?
For example:
the public key is : 04acad3942581b4b1992586....
when extracting it in Go i get: 3076301006072a8648ce3d020106052b81040022036200[then pe public key]
The code looks like this:
pub_key_str := cert.RawSubjectPublicKeyInfo
pub_key_hex := hex.EncodeToString(pub_key_str)
Related
My goal is to monitor the hello directory for any new file creation. Once new file created it should trigger API and upload the file which got created inside the hello directory into azure. I'm getting below exception. Can someone help me on this ?
WatcherRoute.java
#Service
public class WatcherRoute extends RouteBuilder {
#Override
public void configure() {
String accessKey = "key";
String baseUrl = "base/url";
from("file-watch:hello?events=CREATE&antInclude=**/*.txt&recursive=true")
.to("direct:start","direct:uploadFileToBlob")
.end();
from("direct:uploadFileToBlob")
.to("azure-storage-blob://storage-account-name/containerName?blobName=test.txt&accessKey="+getBase64EncodedCipherText(accessKey))
.end();
from("direct:start")
.setHeader(Exchange.HTTP_METHOD, constant("GET"))
.setHeader("Content-Type",constant("application/json"))
.to(baseUrl)
.process(logResponse)
.end();
}
private String getBase64EncodedCipherText(String cipherText) {
byte[] cText = cipherText.getBytes();
return Base64.getEncoder().encodeToString(cText);
}
}
Exception Trace:
2021-12-29 09:33:59.604 ERROR 78488 --- [elFileWatchPoll] o.a.c.p.e.DefaultErrorHandler : Failed delivery for (MessageId: 18CB93B18D0D95B-0000000000000001 on ExchangeId: 18CB93B18D0D95B-0000000000000001). Exhausted after delivery attempt: 1 caught: com.azure.storage.blob.models.BlobStorageException: If you are using a StorageSharedKeyCredential, and the server returned an error message that says 'Signature did not match', you can compare the string to sign with the one generated by the SDK. To log the string to sign, pass in the context key value pair 'Azure-Storage-Log-String-To-Sign': true to the appropriate method call.
If you are using a SAS token, and the server returned an error message that says 'Signature did not match', you can compare the string to sign with the one generated by the SDK. To log the string to sign, pass in the context key value pair 'Azure-Storage-Log-String-To-Sign': true to the appropriate generateSas method call.
Please remember to disable 'Azure-Storage-Log-String-To-Sign' before going to production as this string can potentially contain PII.
Status code 403, "<?xml version="1.0" encoding="utf-8"?><Error><Code>AuthenticationFailed</Code><Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:{id}
Time:2021-12-29T15:33:59.4459965Z</Message><AuthenticationErrorDetail>The MAC signature found in the HTTP request 'example' is not the same as any computed signature. Server used following string to sign: 'GET
You can try with using the below solutions:
Solution 1:
If you used the primary connection string, try with changing the connection string to secondary
Solution 2:
Authentication for Azure Storage is not simply a matter of providing the access key (that is not very secure). You need to create a signature string that represents the given request, sign the string with the HMAC-SHA256 algorithm (using your storage key to sign), and encode the result in base 64. See https://msdn.microsoft.com/en-us/library/azure/dd179428.aspx for the more details.
Solution 3:
If you are using shared access signature (SAS) for Authentication ,Check if its expired and recreate it and run again.
For more details refer this SO Thread:
I inject p7s to a Pdf using code below:
PdfWriter pdfWriter = new PdfWriter("results/final1.pdf");
PdfDocument document = new PdfDocument(new PdfReader("results/prepared1.pdf"), pdfWriter, new StampingProperties().UseAppendMode());
Stream output = new FileStream("results/signed1.pdf", FileMode.Create);
ExternalInjectingSignatureContainer container2 = new ExternalInjectingSignatureContainer(_p7s);
List<byte[]> crlCollection = new List<byte[]>();
crlCollection.Add(File.ReadAllBytes(#"ks/mycrls.crl"));
PdfSigner.SignDeferred(document, "Signature1", output, container2);
Found this
I found this
I tried it as below:
ICrlClient clrClient = new CrlClientOffline(File.ReadAllBytes(#"ks/mycrls.crl"));
addLTV("results/signed1.pdf", "results/final1.pdf", null, clrClient, null);
I did not see the Ltv enabled?
but the result is: Revocation checks were not performed.
addLtv
public static void addLTV(String src, String dest, IOcspClient ocsp, ICrlClient crl, ITSAClient itsaClient)
{
PdfReader reader = new PdfReader(src);
PdfWriter writer = new PdfWriter(dest);
PdfDocument pdfDoc = new PdfDocument(reader, writer, new StampingProperties().UseAppendMode());
LtvVerification v = new LtvVerification(pdfDoc);
SignatureUtil signatureUtil = new SignatureUtil(pdfDoc);
IList<string> names = signatureUtil.GetSignatureNames();
String sigName = names[names.Count - 1];
PdfPKCS7 pkcs7 = signatureUtil.ReadSignatureData(sigName);
if (pkcs7.IsTsp())
{
v.AddVerification(sigName, ocsp, crl, LtvVerification.CertificateOption.WHOLE_CHAIN,
LtvVerification.Level.OCSP_CRL, LtvVerification.CertificateInclusion.NO);
}
else
{
foreach (var name in names)
{
v.AddVerification(name, ocsp, crl, LtvVerification.CertificateOption.WHOLE_CHAIN,
LtvVerification.Level.OCSP_CRL, LtvVerification.CertificateInclusion.YES);
v.Merge();
}
}
pdfDoc.Close();
}
ExternalInjectingSignatureContainer
internal class ExternalInjectingSignatureContainer :IExternalSignatureContainer
{
public ExternalInjectingSignatureContainer(byte[] signature)
{
Signature = signature;
}
public void ModifySigningDictionary(PdfDictionary signDic)
{
}
public byte[] Sign(Stream data)
{
return Signature;
}
public byte[] Signature;
}
I want to improve it by adding the CRL Info (Offline), I have created a .crl file but I don't know how to add the crl while injecting .p7s?
TimeStamp
I know this is not related to this question, but after this I will add a timestamp to the signature, where can I find free timestamp (for development purpose)?
any help would be appreciated..
many thanks in advance
Don
How to add Ltv & CRL (offline) while injecting .p7s to a Pdf?
This depends on the profile of the PDF signatures you create and the capabilities of the validators.
PKCS#7 Signatures as used in ISO 32000
The PDF standard, ISO 32000 both in part 1 and part 2, in section 12.8.3.3 ("PKCS#7 Signatures as used in ISO 32000" / "CMS (PKCS #7) signatures") defined a profile for CMS signatures in PDFs.
This profile requires Revocation information to be included in the CMS container as an signed attribute.
Judging by your previous questions, you create the CMS signature container itself externally. To embed CRLs according to this profile, therefore, you have to update your external code producing the CMS container or (if some service not implemented by you creates those signatures) ask the signature creation service provider to update their code producing the CMS container to include the CRL in a signed attribute as detailed in ISO 32000 section 12.8.3.3.2 ("Revocation Information" / "Revocation of CMS-based signatures").
CAdES signatures as used in PDF
ETSI originally in TS 102 778, updated in EN 319 142, defined profiles (PAdES profiles) for CAdES signatures in PDFs. CAdES is a special profile of CMS. A rundown of these profiles has been copied into the updated PDF specification ISO 32000-2, section 12.8.3.4 ("CAdES signatures as used in PDF").
These profiles require revocation information to be embedded in an incremental update after the signed revision in a Document Security Store structure of PDF objects.
To embed CRLs according to these profiles, therefore, you take the signed PDF and add the CRL afterwards. This essentially is what your addLTV example does.
Why Revocation checks were not performed
In comments you mention that you use PAdES and add the CRL using your addLTV example but that Adobe Reader tells you that "Revocation checks were not performed."
If you read the text underneath that message, the cause becomes clear:
The selected certificate does not chain up to a certificate designated as trusted anchor (see the Trust Tab for details). The result is that revocation checks were not performed on this certificate.
If your validator cannot trace your signer certificate back (in a certificate chain) to a certificate it explicitly trusts, validation stops with an unknown validity. Revocation checks only make sense if the validator trusts the issuer of the signer certificate (directly or indirectly); only in this case of trust by issuer the validator needs to verify whether the issuer revoked the certificate.
I have this requirement, where the app is dustributed, so endpoints are per company, nothing centralized. The issue is the app needs to allow for self-signed certificates.
Obviously I cannot just hardcode the certificate in the app and use the milions of the snippets available to do this.
So, is there a way upon such SSL exception that the cert is untrusted, then to show the user "This certificate is not trusted bla bla. Accept?".
TLDR; how to get offending certificate contents in OkHttp, so it then can be saved in sslSocketFactory subclass?
You can adapt something like the following example code
private fun createInsecureTrustManager(): X509TrustManager = object : X509TrustManager {
override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {}
override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {
val s = "Do you want to accept {${chain.first().subjectX500Principal.name}}?"
val response = JOptionPane.showConfirmDialog(null, s, "Confirm",
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE)
if (response == JOptionPane.NO_OPTION) {
throw CertificateException("Not accepting ${chain.first().subjectX500Principal.name}}")
}
}
override fun getAcceptedIssuers(): Array<X509Certificate> = arrayOf()
}
Adding it to the keystore shouldn't need to be the goal, you should just be able to accept it before the keystore verification is run. n.b. This example should probably fall back to the default logic, but it should get you started.
Using Java API, I am trying to access Public key stored in Luna HSM. Even though I am able to print the corresponding public key label name, but when I am trying to get the public key, I am not able to get the reference to that public key. Here is the code snippet:
KeyStore ks = KeyStore.getInstance("Luna");
ks.load(null, null);
lunaProvider = ks.getProvider();
publicKey = (PublicKey) ks.getKey(alipayImpl.getHsmKeyStorePublicEntryName(), null);
// ****************************************************************************
// ** If the private keystore is not found, return original barcode string. **
// ****************************************************************************
if (publicKey == null) {
throw new Exception("Unable to acquire the Public Key " + alipayImpl.getHsmKeyStorePublicEntryName() + ", Hash will not be verified.");
}
// ***********************************************************
// ** Create a Signature Object and sign the encrypted text **
// ***********************************************************
Signature signatureObject = Signature.getInstance(alipayImpl.getAlipaySignAlgorithm(), lunaProvider);
signatureObject.initVerify(publicKey);
signatureObject.update(signedMessage
.getBytes(AlipayConstants.INPUT_CHARSET_VALUE));
isValidSign = signatureObject.verify(Base64.decode(hash));
I am logging to HSM properly. While Accessing Private Key, I didnt have any issues. Is there any restriction on Luna HSM that access to public key is given only through Certificates?
Thanks in advance.
The correct answer is >
LunaKey lk= LunaKey.LocateKeyByAlias("publicKeyName");
But it is advisable to make the key persistent before querying HSM.
Did you try something like this :
final KeyStore keyStore = KeyStore.getInstance("Luna");
keyStore.load(null, null);
final Certificate certificate = keyStore.getCertificate(alias);
if (certificate == null) {
throw new IllegalArgumentException(String.format("Certificate '%s' does not exists", alias));
}
final PublicKey publicKey = certificate.getPublicKey();
// TODO Working with the public key...
In Java keystore there is no PublicKeyEntry and that's the reason why you're not able to access your public key.
https://docs.oracle.com/javase/8/docs/api/java/security/KeyStore.Entry.html
Java's KeyStore.KeyEntry interface has three implementing classes.
PrivateKeyEntry
SecretKeyEntry
TrustedCertificateEntry.
Java expects you to get retrieve a public key out of your certificate. Sebastien Vanmechelen has given you the perfect example on how to do that.
If by any chance, your Luna HSM partition does not have a X509 certificate then using LunaKey is the only alternative.
I am trying to import RSA private keys into the keychain using my application. The first time I import a key using SecKeychainImport() the operation is successful, a subsequent import gives me an EINVAL (100022) error.
This does not happen if I quit and relaunch the app between two imports. I am including the source code below.
CFArrayRef array = (CFArrayRef)[NSMutableArray array];
SecExternalFormat format = kSecFormatUnknown;
//We are always storing a private key…
SecExternalItemType type = kSecItemTypePrivateKey;
SecKeyImportExportParameters params;
SecKeychainRef keychain;
SecKeychainCopyDefault(&keychain);
memset(¶ms, 0, sizeof(params));
params.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
params.flags = kSecKeyNoAccessControl;
params.keyUsage = CSSM_KEYUSE_ANY;
params.keyAttributes = CSSM_KEYATTR_EXTRACTABLE;
err = SecKeychainItemImport((CFDataRef)data,
(CFStringRef)#"pem",
&format,
&type,
0,
NULL,
keychain,
&array);
if(err == noErr)
{
//Change the kSecKeyPrintName attribute of the keychain item.
}
else
{
//Handle the error by displaying appropriate alert.
}
Am I missing anything obvious?
Try setting the CSSM_KEYATTR_PERMANENT bit in params.keyAttribute. On Lion, I can import multiple PEM-armoured RSA private keys (generated with openssl genrsa) into a keychain if I explicitly set this attribute. If I don't, I get errSecItemNotFound (-25300) when importing the very first key.
(Don't forget to remove kSecKeyNoAccessControl before deploying this code in production. Also, if you generate the key yourself, consider using SecKeyGenerate/SecKeyGenerateSymmetric instead.)