I'm complete beginner in the world of cryptography. I have 2 files - one of them is a digital signature(p7s, signedData) and file which I should verify signature with. The question is how can I do that using Java? Firstly I thought that I can do like this
String rawString = ASN1ObjectIdentifier.fromByteArray(bytesArray).toString();
String rawStringForSurname = rawString.substring(rawString.indexOf("2.5.4.4,") + 9, rawString.length());
String signSurname = rawStringForSurname.substring(0, rawStringForSurname.indexOf("]"));
String rawStringForGivenName = rawString.substring(rawString.indexOf("2.5.4.42,") + 10, rawString.length());
String signGivenName = rawStringForGivenName.substring(0, rawStringForGivenName.indexOf("]"));
Which is awful, obviously. My input data is only intended to have one file (p7s file, which is later decoded to ASN.1 and verifies surname and fullName with author's (data from outside, string)). Surprisingly it turned out, that I should have a file which I should verify sign with as well. I know that there's strange hashcodes logic(that file is intact and the sign is related EXACTLY to the file). The question is how can I retrieve this data from file and sign? And what exactly should I compare in order to accept or reject it? The library I use is Bouncy Castle.
I use Demoiselle Framework to solve this in my project.
Especially the Signer Part
Maybe this share of code can help you too
For Example:
```java
package stackoverflow.my.pack;
import java.nio.file.Path;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import org.bouncycastle.asn1.x509.Certificate;
import org.demoiselle.signer.policy.engine.factory.PolicyFactory.Policies;
import org.demoiselle.signer.policy.impl.cades.factory.PKCS7Factory;
import org.demoiselle.signer.policy.impl.cades.pkcs7.PKCS7Signer;
public class MySigner {
private static PKCS7Signer signerLoader() {
PKCS7Signer signer = PKCS7Factory.getInstance().factoryDefault();
PrivateKey pk = MyReader.getPrivateKey();// Create some method to get your PK
signer.setPrivateKey(pk);
X509Certificate certificate = MyReader.getMyPublicKey();// Create some method to get your Pub
signer.setCertificates((Certificate[]) Arrays.asList(certificate).toArray());
if (is2048(privateKey)) {
signer.setSignaturePolicy(Policies.AD_RB_CADES_2_2);
} else {
signer.setSignaturePolicy(Policies.AD_RB_CADES_1_1);
}
return signer;
}
public static byte[] myMethodToSign(byte[] fileToBeSigned) throws MySignerException {
PKCS7Signer signer = signerLoader();
return signer.doHashSign(fileToBeSigned);
}
}
```
Demoiselle use BouncyCastle too, you can see their sign method to helps you.
You have to load your PK, add BouncyCastle as your Provider, get your SignPolicy Information, validate certificate chain, get a data generator and build your attribute table.
The way Demoiselle do.
If you want to see an example of using their Signer:
https://github.com/demoiselle/signer/blob/master/signer-examples/src/main/java/org/demoiselle/signer/signer/examples/Signer.java
Related
My Requirement :
I am receiving encoded String from one of my REST Api Now this encoded string need to be decode using Base64 decoder .
As This contain files I need to decode like Base64 to File, this can happen using below link, If I just copy paste below encoded string into below link, it gives me files to download
https://base64.guru/converter/decode/file
Now My Question, Is it possible to convert below encoded String to Java Object directly somehow rather converting them into file.
My Ultimate goal is to bring data from encoded string.
-----Right now the flow is-------
EncodedString ==> Convert Base 64 to CSV File and download the files ==> Read CSV File using Java ==>> Data available In Java Object
----Can below possible ?-------
EncodedString ==> Decode and Convert File into Java Object ==>> Data available In Java Object
Encoded String :
What I have tried
package com.oracleerp;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Base64;
public class Zip {
public static void main(String args[]) throws IOException {
convertZipAndDownload();
}
private static void convertZipAndDownload() throws IOException {
try {
String str1 = "UEsDBBQACAgIACFyvVIAAAAAAAAAAAAAAAAwAAAAUk9MRV9OQU1FXzM4OTM0NV8wNS0yOS0yMDIxXzE0LTE0LTAwX0RhdGFTZWMuemlwC/BmZhFh4ODgYOAs2hvEgAQMgdg/yDHe1SM83tU3wMc/0tU1PtzVx8fPNTg43tfRz9HdNSjey98p3iWxJDE4NVkvubjs7ATDvMMGPK7f5yh90JFtmlaXy2akGZDD7C+1q+Tl3+sWZdwsjtZiL5we2NvVCJiEmPbvC2O53DTDRHnDGYOyJzs2z0xMyYybL77bZ6vbQtZEI6H+s5naZ57cZ5jU/+OT1snIpxuMo4zWlQuU7FH4Kf48jHute8LNVyqKZj/4n5R/X/jXxGTaygX3/eUOLXCT/bw1eaVr+IL4wK4FW/dNuMDyWlz2/4HfFf/vLHtRWc0292Xvjgs74r/sv/mSLcCbnUNkp9ryLUAPqzAxMAR4MzKJMCACBVnOkAEdkBxEAd6sbCCNjEAYD6SFGUE8AFBLBwiS+GjvMwEAAIgBAABQSwMEFAAICAgAIXK9UgAAAAAAAAAAAAAAADUAAABST0xFX05BTUVfMzg5MzQ1XzA1LTI5LTIwMjFfMTQtMTQtMDBfSGllcmFyY2hpY2FsLnppcAvwZmYRYeDg4GDgLNobxIAErIDYP8gx3tUjPN7VN8DHP9LVNT7c1cfHzzU4ON7X0c/R3TUo3svfKT4jOTfeIzO1KLEoOSMzOTFHL7m47G3Y2b7ZBhJ7vmuumeN5/2DhPrbtP9yPeR05ueiIZ+DBvoZ3q/LjrU28m8y0v07zsrxZYzxP8qSyJGuQxt4rrS0tyWycsepeKRts6ueUZ886zSN+XfhE56Kg4IPCOk87AuY1LZK6dtpYfemCDUqZhuz3lO9HnNmovVnSZUNbb4ArU0zwXEbu1ysKbXcI7mdUe+rfPeeTL5vaK71JrFuWH/u/TextzmWL2987pq6zuaWX4JTI/PIcw+SZGgxn+Db1OM+TbrO812AUf/SVfIV8ZeD29fGv/q7f5Dj3rf+9r1+/H1vU/D5A2nOr9SKh0H3WP9fJ6FTt9ZhjVf/m1Lb/Mi51IW//S1irvll/lWvHzaAbMzc06oc8Z/v8dYq31i5enZjQwKTUubZXnPu9ttefFnu47OP6RKtNbPXtP3IOPT46b5bA455nwRJrDX6KvTvzZMG2KQeW8id3aE55d+pV+pfTud+DwsteHbHszF0rPcHeR/Cb2aULBZbX+587LUn3lNP/dlx1oleOSNr3XYruC6unbpj+ofh5uqic4beQ1hDBZs5OyUcTOI6x9HeL2PxhOnO/74Djke1ryws53z38d7/WWmmjVOdVacMpD/kDvNk5LNQ1525hBMY8JwNDgDcjkwgDInUgy1kxoAPy00qANysbyARGIMwA0jJMIB4AUEsHCLtpFhpLAgAAmgIAAFBLAwQUAAgICAAhcr1SAAAAAAAAAAAAAAAAFgAAAERpYWdub3N0aWNzXzM4OTM0NS56aXAL8GZmEWHg4OBgOFC4N4gBCYgBsUtmYnpefnFJZnJxvLGFpbGJqV5OfvrckNt5txwEar+HnzHW2tfAeyNI/s6VXGHBHh7eV8JRbxjDjF6/jbu0JP5+rHBIlILJVp3T257NMU7Xu/2yxGpCEd92UYPY6w4W8yfIvrPXinxQ7ssatqDFbUXBUnPL8C2JG9S2uixP/hivyqWwpmnRSsFLm1w0Fa+KhgYo5Lc07U5jbU3r2XTWesMcDdE7dT4L7Lt+J25ZvtHxpvC0XU/DS9KbTvSp2+4XL/m74na3Iodw8e990u3Nthn7XE/McJr9eMvDXWq6Vf/OCB77yWwz4ZaKn6qKq925aZO/2FmzbmOLun3vnvPvvMBtPMs/bksId6oLPici6HWoaVXu7ONbf/SEhi++XXXLJV9qGUfqJ5+cdaLXubQu7wsyfbST9+MW+Qqg3+Y9Dz7/QCRRtWpZ/LyI8Hv7pOMWT/3MGbrT9C1T0jMHCU3O7FMr7kiVLnrwfpmLp8jOQIkdBhd3T914aQ2/hneKg6fJJ+cLx5b53jnXuiQ3atI/lwr+RHs+v9Dd3xitt8wp8v75P7Ww7anFavvUnQv6txw7W3p8o3TPoeS1yS8cE67I8+hz7Dl7R4HT7Z2C3DzRmqOJ+u/6ZY77HWmzU8rmLrockubQVTKzNlJn8++XFv+npZ52NZPz33Qzp3K+36XzkRv3nLa/sfIhk6oR6xRHhiDOU4G70kKnKiytKnxqFXzxxtHt9/97nY27kRD97tbBvRWyE7f71d/4W7FYuNpJts9c+ceqeY9viDqHva023F8iwXuG/7o8Xz1jgDc7R/RNG3ZVJgYGD1YGhgBvRiYRBkRSQ5YTY0AH2BNegDcrG0iWEQhdgHQmE4gHAFBLBwhX8CMYnAIAAMMCAABQSwECFAAUAAgICAAhcr1Skvho7zMBAACIAQAAMAAAAAAAAAAAAAAAAAAAAAAAUk9MRV9OQU1FXzM4OTM0NV8wNS0yOS0yMDIxXzE0LTE0LTAwX0RhdGFTZWMuemlwUEsBAhQAFAAICAgAIXK9UrtpFhpLAgAAmgIAADUAAAAAAAAAAAAAAAAAkQEAAFJPTEVfTkFNRV8zODkzNDVfMDUtMjktMjAyMV8xNC0xNC0wMF9IaWVyYXJjaGljYWwuemlwUEsBAhQAFAAICAgAIXK9UlfwIxicAgAAwwIAABYAAAAAAAAAAAAAAAAAPwQAAERpYWdub3N0aWNzXzM4OTM0NS56aXBQSwUGAAAAAAMAAwAFAQAAHwcAAAAA";
byte[] decodedImg = Base64.getDecoder().decode(str1.getBytes(StandardCharsets.UTF_8));
Path destinationFile = Paths.get("/Users/as.asd/Documents/zip", "myImage1.zip");
Files.write(destinationFile, decodedImg);
} catch (Exception e) {
System.out.println("Error :" + e.getMessage());
}
}
}
This works fine to download zip, but I want to do all this operation in Memory without doing any downloading stuff
Yes, you can easily decode Base64 data to byte[] in Java using java.util.Base64 like this:
String myBase64String = ...;
byte[] decoded = Base64.getDecoder().decode(myBase64String);
Note that you might need to replace getDecoder() with either getMimeDecoder() or getUrlDecoder(), depending on what type of Base64 encoding your string used.
Then if you need some kind of processing that needs that data as an input you can easily create an InputStream that provides that data using an ByteArrayInputStream:
InputStream in = new ByteArrayInputStream(decoded);
If however, your processing code insists on taking a File object, then you'll need to modify that code to accept an InputStream directly (usually that's easy, because most of those methods simply create a FileInputStream and read that, just skip that step and used the passed-in InputStream instead).
I have setup a Java program that I made for my apprenticeship project that takes in a JSON file of English strings and outputs a different language JSON file that is defined in the console. Some languages like french and Italian will output with the correct translations whereas Russian or Japanese will output with question marks as seen in the images bellow.
I had searched around at saw that I needed to get the bytes of my string and then encode that to UTF-8 I did do this but was still getting question marks so I started to use he standard charsets built into Java and tried different ways of encoding/decoding the string I tried this:
and this gave me a different output of this : Ð?Ñ?ивеÑ?
package com.bis.propertyfiletranslator;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.util.List;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.translate.Translate;
import com.google.api.services.translate.model.TranslationsListResponse;
import com.google.api.services.translate.model.TranslationsResource;
public class Translator {
public static Translate.Translations.List list;
private static final Charset UTF_8 = Charset.forName("UTF-8");
private static final Charset ISO = Charset.forName("ISO-8859-1");
public static void translateJSONMapThroughGoogle(String input, String output, String API, String language,
List<String> subLists) throws IOException, GeneralSecurityException {
Translate t = new Translate.Builder(GoogleNetHttpTransport.newTrustedTransport(),
JacksonFactory.getDefaultInstance(), null).setApplicationName("PhoenUX-Google-Translate").build();
try {
list = t.new Translations().list(subLists, language).setFormat("text");
list.setKey(API);
} catch (GoogleJsonResponseException e) {
if (e.getDetails().getMessage().equals("Invalid Value")) {
System.err.println(
"\n Language not currently supported, check the accepted language codes and try again.\n\n Language Requested: "
+ language);
} else {
System.out.println(e.getDetails().getMessage());
}
}
for (TranslationsResource translationsResource : response.getTranslations()) {
for (String key : JSONFunctions.jsonHashMap.keySet()) {
JSONFunctions.jsonHashMap.remove(key);
String value = translationsResource.getTranslatedText();
String encoded = new String(value.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
JSONFunctions.jsonHashMap.put(key, encoded);
System.out.println(encoded);
break;
}
}
JSONFunctions.outputTranslationsBackToJson(output);
}
}
So this is using the google cloud library, I added a sysout so I could see the results of what I had tried, so this code should be all you need to replicate it.
I expect the output of "Hello" to be "Привет"(russian) actual output is ???? or Ð?Ñ?ивеÑ? dependent on the encoding I use.
String encoded = new String(...) is dead wrong. Just
put(key, value):
Note that System.out.println will always have problems as the OS encoding might be some Windows ANSI encoding. Then it is likely non Unicode-capable - and String contains Unicode.
I want to make a custom ASN.1 structure, what consists of 3 PrintableString's and 1 OctetString. I am using BouncyCastle framework to work with this.
So I set in my class the needed parameters, and now I have to return this structure in ASN.1 format, and then encode it with Base64 (its parameter is byte[]), then into PEM format.
So my question is, that what type of object do I have to return from method getASN1format()?
My code:
import org.bouncycastle.asn1.*;
import java.io.IOException;
public class ASN1Handshake1 implements ASN1Encodable {
private DERPrintableString A, B, ID_PASS;
private ASN1OctetString ID_K;
public ASN1Handshake1(String A, String B, String ID_K, String ID_PASS, TTP TTPs ) throws IOException {
this.A = new DERPrintableString(A);
this.B = new DERPrintableString(B);
this.ID_K = new DEROctetString(ID_K.getBytes());
this.ID_PASS = new DERPrintableString(ID_PASS);
}
public ?? getASN1format(){
//TODO
}
#Override
public ASN1Primitive toASN1Primitive() {
return null;
}
}
I'm using Bouncy Castle 1.57 (bcprov-jdk15on) for this code.
First of all, keep in mind that ASN.1 is not a format per se, it's a description language that defines a structure, and PEM is a format that uses base 64. Many cryptography standards use ASN.1 to define their data structures, and PEM or DER (Distinguished Encoding Rules) to serialize those structures.
So, if you want to get the ASN.1 structure and format it to base64, you can do as below. You don't need a getASN1format method, just use the existent ones.
The fields can't just be "loose" in the ASN.1 structure. So I decided to put them in a sequence (using org.bouncycastle.asn1.DERSequence class), which is the best choice to store fields of a structure. I put them in the order they're declared, but of course you can choose any order you want.
I've also changed the variables names to follow Java's code conventions (names start with lowercase letters). So the class code is:
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DERPrintableString;
import org.bouncycastle.asn1.DERSequence;
public class ASN1Handshake1 extends ASN1Object {
private DERPrintableString a, b, idPass;
private ASN1OctetString idK;
// removed TTPs parameter (it wasn't using it)
public ASN1Handshake1(String a, String b, String idK, String idPass) {
this.a = new DERPrintableString(a);
this.b = new DERPrintableString(b);
this.idK = new DEROctetString(idK.getBytes());
this.idPass = new DERPrintableString(idPass);
}
// returns a DERSequence containing all the fields
#Override
public ASN1Primitive toASN1Primitive() {
ASN1Encodable[] v = new ASN1Encodable[] { this.a, this.b, this.idK, this.idPass };
return new DERSequence(v);
}
}
To create a handshake object and convert it to base64 (the code below is not handling exceptions, so add the try/catch block accordingly):
import org.bouncycastle.util.encoders.Base64;
// create handshake object with some sample data
ASN1Handshake1 handshake = new ASN1Handshake1("a", "b", "ID_K", "ID_PASS");
// convert it to base64
String base64String = new String(Base64.encode(handshake.getEncoded()));
System.out.println(base64String);
This will output the handshake structure in base64 format:
MBUTAWETAWIEBElEX0sTB0lEX1BBU1M=
Please note that this is not a complete PEM (with headers like -----BEGIN CERTIFICATE-----) because your custom structure is not a predefined standard. So, you'll have to stay with this base64 generic string.
To check that the base64 string contains the ASN.1 sequence, just do:
// read from base64 String
ASN1Sequence seq = (ASN1Sequence) DERSequence.fromByteArray(Base64.decode(base64String.getBytes()));
int n = seq.size();
for (int i = 0; i < n; i++) {
ASN1Encodable obj = seq.getObjectAt(i);
if (obj instanceof DEROctetString) {
System.out.println(new String(((DEROctetString) obj).getOctets()));
} else {
System.out.println(obj);
}
}
The output is:
a
b
ID_K
ID_PASS
i find below code for Cracking Md5 hashes : (from : aboulton.blogspot.com.tr)
package md5crack;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* #author Adam Boulton - Using Google to crack MD5
*/
public class MD5Cracker {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
if(args[0] == null || args[0].isEmpty())
{
System.out.println("-= Google MD5 Cracker =-");
System.out.println("-= Adam Boulton - 2010 =- ");
System.out.println("Usage: MD5crack <hash>");
}
String hash = args[0];
String url = String.format("https://www.google.com/search?q=%s", hash);
try {
URL oracle = new URL(url);
URLConnection conn = oracle.openConnection();
//keep Google happy, otherwise connection refused.
conn.setRequestProperty("user-agent", "Mozilla/5.0 Windows NT6.1 WOW64 AppleWebKit/535.7 KHTML, like Gecko Chrome/16.0.912.63 Safari/535.7");
BufferedReader in = new BufferedReader(
new InputStreamReader(
conn.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
String[] words = inputLine.split("\\s+");
for (String word : words) {
String wordHash = DigestUtils.md5Hex(word);
if (wordHash.equals(hash)) {
System.out.println("[*] Found: " + word);
System.exit(0);
}
}
}
System.out.println("[!] No results.");
in.close();
} catch (IOException ex) {
Logger.getLogger(MD5Cracker.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
but in this line i have an error :
String wordHash = DigestUtils.md5Hex(word);
Error :
DigestUtils cannot be resolved
How can i fix that ?
and this is good method or Class for crack and finding Decoded MD5 hash ?
How we can use this with Optimizing on android ?
Thanks.
Your program doesn´t know what DigestUtils is standing for.
You need to either import it, or download codec from the appache common jar and reference it as external jar into your project and import it afterwards
... and this is good method or Class for crack and finding Decoded MD5 hash?
Is it going to be effective? In general, probably not.
There are 340,282,366,920,938,463,463,374,607,431,768,211,456 possible different MD5 hashes. If you have an MD5 hash for an arbitrary string or document, then the chances of finding that hash in Google search results is vanishingly small.
Indeed, it is pretty obvious that Google's search engines wouldn't be able to index more than a miniscule fraction of the possible MD5 hashes. According to this article, the "big 4" internet companies were estimated to have ~1,200 Petabytes of storage in 2013. That's a factor of ~1020 too small just to store all possible MD5 hashes.
However, if you can identify a use-case where mappings between relevant strings and MD5 hashes are systematically published in web pages, then this approach might work ... for those strings. One such use-case would be MD5 hashes for email addresses, if someone has published the mappings in pages that Google indexes.
Does this code require the Digital Persona One Touch RTE (Runtime environment) to work?:
DPFPVerification verifier = DPFPGlobal.getVerificationFactory().createVerification();
If so, is there another way to verify Digital Persona SampleFeatures (serialized) against a Digital Persona Template (serialized) using only the dpfp JARs?
Reason: We plan to have our DPFP verifier on a Web Service provided by TIBCO.
Any help is greatly appreciated!
I get a Java JNI exception with this sample test main code:
import com.digitalpersona.onetouch.DPFPFeatureSet;
import com.digitalpersona.onetouch.DPFPFeatureSetFactory;
import com.digitalpersona.onetouch.DPFPGlobal;
import com.digitalpersona.onetouch.DPFPTemplate;
import com.digitalpersona.onetouch.DPFPTemplateFactory;
import com.digitalpersona.onetouch.verification.DPFPVerification;
import com.digitalpersona.onetouch.verification.DPFPVerificationResult;
public class Main {
/**
* fingerScanTemplate is from WC DB
* sample is from the WS input parameters
*/
public boolean performVerification(byte[] fingerScanTemplate, byte[] sampleFeatures) {
DPFPTemplateFactory templateFactory = DPFPGlobal.getTemplateFactory();
DPFPFeatureSetFactory featureSetFactory = DPFPGlobal.getFeatureSetFactory();
DPFPVerification verifier = DPFPGlobal.getVerificationFactory().createVerification();
// Deserialize template & sampleFeature
DPFPTemplate deserializedTemplate = templateFactory.createTemplate(fingerScanTemplate);
DPFPFeatureSet features = featureSetFactory.createFeatureSet(sampleFeatures);
//Compare the feature set with the template, based on which finger was captured
DPFPVerificationResult result = null;
result = verifier.verify(features, deserializedTemplate);
return result != null && result.isVerified();
}
/**
* #param args
*/
public static void main(String[] args) {
new Main().performVerification(null, null);
}
}
No you should not need some sort of RTE. I do know that I had to have the One Touch SDK installed because it runs a windows service called Biometric scanning or something similar. The main problem I see with your code is that:
DPFPVerificationResult result = null;
result = verifier.verify(features, deserializedTemplate);
Needs to be:
DPFP.Verification.Verification.Result result = new DPFP.Verification.Verification.Result();
verifier.verify(features, template, ref result );
At least that is what got my code to start verifying correctly. I also had to fix a programmer's mistake in creating the FeatureSet which needs to be done like this:
DPFP.FeatureSet features = ExtractFeatures(Sample, DPFP.Processing.DataPurpose.Verification);
I have a feeling you are using an older SDK than I am but maybe this will help out some.