Below is a snippet of my code on generating signature:
File file = new File("privatekey.pkcs8");
FileInputStream fis = new FileInputStream(file);
pemBytes = new byte[fis.available()];
fis.read(pemBytes);
fis.close();
File filedata = new File("hi");
FileInputStream fis2 = new FileInputStream(filedata);
dataBytes = new byte[fis2.available()];
fis2.read(dataBytes);
fis2.close();
} catch (Exception e) {
e.printStackTrace();
}
PrivateKey privKey=null;
try {
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pemBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
privKey = kf.generatePrivate(keySpec);
} catch (Exception e) {
e.printStackTrace();
}
/* Create a Signature object and initialize it with the private key */
byte[] realSig = null;
try{
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(privKey);
signature.update(dataBytes);
realSig = signature.sign();
byte[] res = Base64.encodeBase64(realSig);
FileOutputStream sigfos = new FileOutputStream("mysignature");
sigfos.write(res);
sigfos.close();
} catch (Exception e) {
e.printStackTrace();
the signature works fine but currently I would like to implement a time stamp function which will cause the signature to expire after sometimes, perhaps 30 days. However, I have no experience dealing with time stamp, I was also unable to find example or tutorials which explain well enough.
Therefore, I would like to ask for links/explanation/tutorial on how to get started!
And if possible, snippet of codes that I could use!
Thanks in advance!
Related
I need to use PublicKey to encrypt session key but I have public key as Base64 encoded string so I tried to convert it as :
KeyFactory kf = KeyFactory.getInstance("RSA"); // or "EC" or whatever
byte[] keyBytes = _publicKey.getBytes();
byte[] publicKeyBytes = Base64.decode(keyBytes, Base64.DEFAULT);
X509EncodedKeySpec publicKeySpecs = new X509EncodedKeySpec(publicKeyBytes);
Log.v("", "X509 KS" + publicKeySpecs);
publicKey = kf.generatePublic(publicKeySpecs);
But I am getting public key as null value and getting exception as :
java.security.spec.InvalidKeySpecException: java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag
If anyone has idea how to do it or have working code then please help me.
Thanks in Advance
Hi guys I generated Public Key from Base64 encoded String .
after wondering for few days this code worked for me.
String _publicKey= base64encoded_publickey;
// InputStream fileInputStream = null;
try {
// Receiving side
byte[] decodedBytes = Base64.decode(_publicKey, Base64.DEFAULT);
fileInputStream = new ByteArrayInputStream(decodedBytes);
// Print the decoded string
String decodedString = new String(decodedBytes);
CertificateFactory certFactory = CertificateFactory
.getInstance(CERTIFICATE_TYPE);
// certFactory.
X509Certificate cert = (X509Certificate) certFactory
.generateCertificate(fileInputStream);
publicKey = cert.getPublicKey();
Log.d("TAG", "Public key of the certificate:" + publicKey);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Could not intialize encryption module",
e);
} finally {
if (keyStream != null) {
try {
keyStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Hope it will help you...Thanks...
well, last time it worked for me (I used bouncyCastle library..), you might need to modify it if it doesn't suit your need..
KeyPairGenerator keyGen = null;
KeyPair kp = null;
keyGen = KeyPairGenerator.getInstance("ECDSA", "BC");
ECGenParameterSpec ecSpec = new ECGenParameterSpec("brainpoolp160r1");
keyGen.initialize(ecSpec, new SecureRandom());
kp = keyGen.generateKeyPair();
EDIT:
(oops my bad, that's for initial generation..)
at that time I stored them as one..
and I need to convert the Base64 string back to array of byte first, and split them into part 1 and part 2..
private void splitKeyPair (byte[] thekeypair, byte[] part1, byte[] part2)
{
System.arraycopy(thekeypair, 0, part1, 0, 68);
System.arraycopy(thekeypair, 68, part2, 0, 115);
}
byte[] part1 = new byte[68];
byte[] part2 = new byte[115];
splitKeyPair(inputBuffer, part1, part2);
fact = KeyFactory.getInstance("ECDSA", "BC");
kp = new KeyPair(fact.generatePublic(new X509EncodedKeySpec(part1)),
fact.generatePrivate(new PKCS8EncodedKeySpec(part2)));
hope it helps..
*note: the size might vary, depending on the spec..
sorry to ask a particular question, but I need to generate in java code a 'signature' like the following code line in ruby:
signature = OpenSSL::PKey::RSA.new(File.read("PUBLIC_PEM_PATH")).public_encrypt('SECRET_KEY')
I have the .pem key file and the SECRET_KEY that's is something like: F6qxlwQTYWRM3gRfgftryKJHKYZiGXdoy5lDm4
How can I do this ?
Thanks!
UPDATE 1
I tried this :
File pubKeyFile = new File(keyFileName);
DataInputStream inputStream;
byte[] signature = null;
try {
inputStream = new DataInputStream(new FileInputStream(pubKeyFile));
byte[] pubKeyBytes = new byte[(int)pubKeyFile.length()];
inputStream.readFully(pubKeyBytes);
inputStream.close();
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(pubKeyBytes);
RSAPublicKey pubKey = (RSAPublicKey) keyFactory.generatePublic(pubSpec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
signature = cipher.doFinal(secretKey.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
return signature;
And got this error:
java.security.spec.InvalidKeySpecException: java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag
UPDATE2
I managed to load a public key from a .pem file. But now, Im getting an error from the cipher.
public static byte[] getSignature(String keyFileName, byte[] secretKey){
byte[] signature = null;
try {
PublicKey pubKey = readKeyFromFile(keyFileName);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
signature = cipher.doFinal(secretKey);
} catch (Exception e) {
e.printStackTrace();
}
return signature;
}
private static PublicKey readKeyFromFile(String keyFileName) throws IOException {
InputStream in = new FileInputStream(keyFileName);
DataInputStream din = new DataInputStream(in);
try {
BigInteger m = BigInteger.valueOf(din.readLong());
BigInteger e = BigInteger.valueOf(din.readLong());
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m, e);
KeyFactory fact = KeyFactory.getInstance("RSA");
RSAPublicKey pubKey = (RSAPublicKey) fact.generatePublic(keySpec);
return pubKey;
} catch (Exception e) {
throw new RuntimeException("Spurious serialisation error", e);
} finally {
din.close();
}
}
The error log:
javax.crypto.IllegalBlockSizeException: input must be under 8 bytes
Any thoughts??
So finally, after hours of research I came with a solution and finally could get read my public key from .pem file and generate an instance of this key. Hence, I managed to encrypt the data.
But I had to copy and paste the key content without any special character like '\n' and make a publicKeyString with it
----------BEGIN RSA PUBLIC KEY---------
key content
----------END RSA PUBLIC KEY---------
static public PublicKey publicKey(String publicKeyString) {
try {
byte[] decodedPublicKey = Base64.decode(publicKeyString, 0);
ASN1InputStream in = new ASN1InputStream(decodedPublicKey);
ASN1Primitive obj = in.readObject();
RSAPublicKeyStructure keyStruct = RSAPublicKeyStructure.getInstance(obj);
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(keyStruct.getModulus(), keyStruct.getPublicExponent());
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(keySpec);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
I failed even when I tried to use PEMReader from bouncy castle. All the problems have something to do with keys generated in Ruby version prior 1.9.3 as described with details here.
Anyway, thanks a lot for the attention disposed.
Looks like key wrapping (encryption) to me. Use bouncy castle to read the PEM file, then use Cipher.getInstance("RSA/ECB/PKCS1Padding") to encrypt the secret key, and base 64 encode the result... You could also try the mode Cipher.WRAP_MODE to see if that works. Note that encryption will always return a different result, the only way to test for compatibility is to decrypt it with the other software.
I have an OpenGL game with two images, one is a texture atlas, and one is a single image. When I try to open the single one to an OpenGL object the application dies when closing it.
The code:
InputStream is = context.getResources().openRawResource(texture);
Bitmap bitmap = null;
try {
bitmap = BitmapFactory.decodeStream(is);
} finally {
try {
is.close();
is = null;
Log.i("log", "try");
} catch (IOException e) {
Log.i("log", "Catch");
}
}
It decodes the InputStream, but it steps into the catch after closing. I really can't understand what is the problem. Opening and closing InputStreams with the other texture works fine.
try the below code to print a stacktrace
final Writer result = new StringWriter();
final PrintWriter printWriter = new PrintWriter(result);
ex.printStackTrace(printWriter);
String stacktrace = result.toString();
Log.i("log", "Catch" + stacktrace);
then hopefully you will have your answer :)
I'm writing a small app that's supposed to mirror moves made on another phone during a game of tetris. It works perfectly for a little while, untill i get a CorruptedStreamException on the server side while writing an object.
Here's the code for the server:
public void run() {
ServerSocket ss = null;
Socket s = null;
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try{
ss = new ServerSocket(PORT);
s = ss.accept();
Log.i(TAG,"accepted");
oos.flush();
ois = new ObjectInputStream(s.getInputStream());
while(run){
busy=true;
oos.writeObject(positions);
busy = false;
this.sleep(100);
oos.reset();
}
} catch (Exception e) {
e.printStackTrace();
}finally{//close sockets!!
try{
ois.close();
oos.close();
s.close();
ss.close();
}catch(Exception e){}
}
}
I'll toss out the client side code too:
public void run() {
Canvas c = null;
Socket s = null;
ObjectInputStream ois = null;
ObjectOutputStream oos = null;
try {
Log.i(TAG, "it entered try");
s = new Socket(IP, PORT);
oos = new ObjectOutputStream(s.getOutputStream());
oos.flush();
ois = new ObjectInputStream(s.getInputStream());
Log.i("try","has connected");
while(run){
blockList=(ArrayList<Posision>)ois.readObject();
if(blockList!=null){
try{
c=mSurfaceHolder.lockCanvas(null);
synchronized(mSurfaceHolder){
mTetrisView.drawTetris(c, blockList);
}
}finally{
if(c!=null){
mSurfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}catch (EOFException ez){
Log.i("catch", "End of file");
} catch (Exception e) {
Log.i("catch",e.getMessage());
e.printStackTrace();
}finally{//close socket!!
try{
ois.close();
oos.close();
s.close();
}catch(IOException e){}
}
}
And a stack trace might come in handy too, when thinking of it:
java.io.StreamCorruptedException
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1712)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1665)
at com.prosjekt.tetris2.ServerThread.run(ServerThread.java:42)
Now why am I getting this error? As far as I know, writeObject() shouldn't be able to throw it.
I'm not really sure how I figured this out, but turns out that the client thread didn't print the errors it got (this however, doesn't explain why the server side threw the corruptedStreamException). The fault lay with the client getting a OptionalDataException with the length field set to 0 (indicates end of stream). I knew for a fact that the writeObject were called often enough that this shouldn't be a problem, so I decided to rewrite part of the code.
The final fix is really too simple, and this is how my while loop at server side looked like after rewriting:
while(run){
oos.writeObject(new ArrayList<Posisions>(positions));
oos.flush();
}
There's viritually no changes to the client side, so I guess the rate of resets() somehow stomped the stream.
So I'm unexpectedly receiving a FileNotFoundException. As you can see, shortly before I call the FileReader, I call FileInputStream which works fine. I've tried putting the FileReader in its own Try/Catch clause, but receive the same result. I've gutted most of the lines unnecessary to my question from this block. (Ultimately I call LineNumberReader as well, though I removed it from the block because I'm not even getting that far.)
String FILENAME = "file.txt";
try {
byte[] buffer = new byte[128];
String toStr = new String();
TextView view = (TextView)findViewById(R.id.textview);
FileInputStream fis = openFileInput(FILENAME); /////File is found successfully here/////
fis.read(buffer);
fis.close();
toStr = new String(buffer);
view.append(toStr);
FileReader fr = new FileReader(FILENAME); /////FileNotFoundExceptionThrownHere/////
/////do stuff here/////
fr.close();
}
catch (FileNotFoundException e) {
TextView view = (TextView)findViewById(R.id.textview);
view.append("file not found!");
}
catch (IOException e) {
TextView view = (TextView)findViewById(R.id.textview);
view.append("IO error!");
}
Also, please keep in mind when answering that I'm still somewhat of a novice when it comes to java. I have experience in a couple other languages but java is a bit of a different breed of monster to me. Any help would be tremendously appreciated!
openFileInput() and new FileReader() do not take the same parameter.
openFileInput("file.txt") is equivalent to new FileReader(new File(getFilesDir(), "file.txt")).