Flexiprovider - How to encrypt/de with formatted keypair - java

Im using flexiprovider to encrypt/de with asymmetric algorithm based on Elliptic Curve following this tutorial. With a little modification, i'm gonna convert the public and the private key into Base64 for personal purpose (like storing into the database or text file). I'm also looking at this question and the answer is refer to this thread. But my code are running for dekstop not in android device, android and dekstop version in java i think is a really big difference (just for clean up my question information). Ok, in my code when im going to create the formatted public key from a generated public key i got an error (i think the same problem will happen when i try to do that for the private key).
Now, here's my code:
Keypair generator class.
import org.jivesoftware.smack.util.Base64; //or whatever to convert into Base64
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.KeyFactory;
import javax.crypto.Cipher;
import de.flexiprovider.common.ies.IESParameterSpec;
import de.flexiprovider.core.FlexiCoreProvider;
import de.flexiprovider.ec.FlexiECProvider;
import de.flexiprovider.ec.parameters.CurveParams;
import de.flexiprovider.ec.parameters.CurveRegistry.BrainpoolP160r1;
import de.flexiprovider.pki.PKCS8EncodedKeySpec;
import de.flexiprovider.pki.X509EncodedKeySpec;
...
Security.addProvider(new FlexiCoreProvider());
Security.addProvider(new FlexiECProvider());
KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECIES","FlexiEC");
CurveParams ecParams = new BrainpoolP160r1();
kpg.initialize(ecParams, new SecureRandom());
KeyPair keyPair = kpg.generateKeyPair();
PublicKey pubKey = keyPair.getPublic();
byte[] encod_pubK = pubKey.getEncoded();
String publicKey = Base64.encodeBytes(encod_pubK);
System.out.println("Public Key :" +publikKey);
PrivateKey privKey = keyPair.getPrivate();
byte[] encod_privK = privKey.getEncoded();
String privateKey = Base64.encodeBytes(encod_privK);
System.out.println("Private Key :" +privateKey);
From that code above im going to store the string "privateKey" and "publicKey". Now im going to encrypt the message.
Sender Side
import (same as code above)
...
Security.addProvider(new FlexiCoreProvider());
Security.addProvider(new FlexiECProvider());
Cipher cipher = Cipher.getInstance("ECIES","FlexiEC");
IESParameterSpec iesParams = new IESParameterSpec ("AES128_CBC","HmacSHA1", null, null);
byte[] decodedPubKey = Base64.decode(publicKey);
X509EncodedKeySpec formatted_public = new X509EncodedKeySpec(decodedPubKey);
KeyFactory kf = KeyFactory.getInstance("ECIES","FlexiEC");
PublicKey publicKey = kf.generatePublic(formatted_public); // <--- I got error when hit this row
cipher.init(Cipher.ENCRYPT_MODE, publicKey, iesParams);
byte[] block = "this my message".getBytes();
System.out.println("Plaintext: "+ new String(block));
byte [] Ciphered = cipher.doFinal(block);
System.out.println("Ciphertext : "+ Base64.encodeBytes(Ciphered));
The error from that sender code above is:
Exception in thread "main" de.flexiprovider.api.exceptions.InvalidKeySpecException: java.lang.RuntimeException: java.security.InvalidAlgorithmParameterException: Caught IOException("Unknown named curve: 1.3.36.3.3.2.8.1.1.1")
at de.flexiprovider.ec.keys.ECKeyFactory.generatePublic(ECKeyFactory.java:205)
at de.flexiprovider.api.keys.KeyFactory.engineGeneratePublic(KeyFactory.java:39)
at java.security.KeyFactory.generatePublic(KeyFactory.java:328)
How can i generate that public key with that named curve: 1.3.36.3.3.2.8.1.1.1 ?
Recipient Side (just for another information)
If the sender has been succesfully encrypt the message, now im going to decrypt the message, here's my code (but not sure if this running without an error like the sender code above):
byte[] decodedPrivateKey = Base64.decode(privateKey);
PKCS8EncodedKeySpec formatted_private = new PKCS8EncodedKeySpec(decodedPrivateKey);
cipher.init(Cipher.DECRYPT_MODE, privKey, iesParams);
byte[] decryptedCipher = cipher.doFinal(Ciphered);
System.out.println("Decrypted message : "+ new String (decryptedCipher));

Due to unsolved error with my code above because i think this flexiprovider aren't compatible with jdk-8 where the bug is in "KeyFactory kf = KeyFactory.getInstance("ECIES","FlexiEC")" line which can't find that named curve, i change and decide to use BouncyCastle provider for doing the EC encryption (ECIES) and it works. But there's a question again come in to my mind, as i can see in the Flexiprovider which is use ("AES128_CBC","HmacSHA1", null, null); as the IESParameterSpec.
But for bouncycastle provider i can't find where is the IESParameterSpec which using AES128_CBC as the iesparameterspec, how can i do that if want to change the iesparam into AES128_CBC when i'm using this bouncy provider ?
Somebody please explain about this iesparam spec in bouncy provider i'm new about this.
Here's my code for information:
Key Pair Generator Class
import codec.Base64; // or whatever which can use to base64 encoding
import static java.lang.System.out;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
...
Security.addProvider(new BouncyCastleProvider());
KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECIES", "BC");
ECGenParameterSpec brainpoolP160R1 = new ECGenParameterSpec("brainpoolP160R1");
// I'm Still using this 160 bit GF(*p*) to keep the algorithm running fast rather than 256 or above
kpg.initialize(brainpoolP160R1);
KeyPair kp = kpg.generateKeyPair();
PublicKey publicKey = kp.getPublic();
PrivateKey privateKey = kp.getPrivate();
byte[] PublicKey = publicKey.getEncoded();
byte[] PrivateKey = privateKey.getEncoded();
out.println("Encoded Public : "+Base64.encode(PublicKey));
out.println("\nEncoded Private : "+Base64.encode(PrivateKey));
...
The Encryption class (sender side)
import codec.Base64;
import codec.CorruptedCodeException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PublicKey;
import java.security.Security;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
...
Security.addProvider(new BouncyCastleProvider());
// Assume that we know the encoded public key then return it by decode the public key
byte[] decodedPublic = Base64.decode("MEIwFAYHKoZIzj0CAQYJKyQDAwIIAQEBAyoABNXclcmtUt8/rlGN47pc8ZpxkWgNgtKeeHdsVD0kIWLUMEULnchGZPA=".getBytes());
X509EncodedKeySpec formatted_public = new X509EncodedKeySpec(decodedPublic);
KeyFactory kf = KeyFactory.getInstance("EC","BC");
PublicKey pubKey = kf.generatePublic(formatted_public);
Cipher c = Cipher.getInstance("ECIES", "BC");
c.init(Cipher.ENCRYPT_MODE, pubKey); // How can i put the AES128_CBC for ies parameter ? is that possible
byte[] cipher = c.doFinal("This is the message".getBytes());
System.out.println("Ciphertext : "+ Base64.encode(cipher));
...
The decryption class (recipient side)
import codec.Base64;
import codec.CorruptedCodeException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.Security;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
...
Security.addProvider(new BouncyCastleProvider());
// Assume that we know the encoded private key
byte[] decodedPrivate = Base64.decode("MHECAQAwFAYHKoZIzj0CAQYJKyQDAwIIAQEBBFYwVAIBAQQUQmA9ifs472gNHBc5NSGYq56TlOKgCwYJKyQDAwIIAQEBoSwDKgAE1dyVya1S3z+uUY3julzxmnGRaA2C0p54d2xUPSQhYtQwRQudyEZk8A==".getBytes());
PKCS8EncodedKeySpec formatted_private = new PKCS8EncodedKeySpec(decodedPrivate);
KeyFactory kf = KeyFactory.getInstance("EC", "BC");
PrivateKey privKey = kf.generatePrivate(formatted_private);
Cipher c = Cipher.getInstance("ECIES");
c.init(Cipher.DECRYPT_MODE, privKey); //How can i adding the **AES128_CBC** ies param ?
// Assume that we know the encoded cipher text
byte[] plaintext = c.doFinal(Base64.decode("BKbCsKY7gDPld+F4jauQXvKSayYCt6vOjIGbsyXo5fHWo4Ax+Nt5BQ5FlkAGksFNRQ46agzfxjfuoxWkVfnt4gReDmpPYueUbiRiHp1Gwp0="));
System.out.println("\nPlaintext : "+ new String (plaintext));
...
Any help would be appriciate !

Related

Javax crypto seems to generate a random RSA public key despite me providing a modular and exponent

I've made the following imports:
import java.math.BigInteger;
import java.security.*;
import java.security.interfaces.RSAPublicKey;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.crypto.*;
import java.util.Scanner;
import java.security.spec.*;
I have declared a variable N as a large BigInteger and done RSAPublicKeySpec pub=new RSAPublicKeySpec(N, new BigInteger("65537"));. I also have a string array ls. To keep the question simple, ls is defined with String[] ls= {"Abc","abc","a"};.
I have used the following code to create a cipher
Cipher cipher= Cipher.getInstance("RSA");
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPublicKey publ=(RSAPublicKey) keyFactory.generatePublic(pub);
System.out.println(publ.getPublicExponent()); System.out.println(publ.getModulus()); System.out.println(N);
cipher.init(Cipher.ENCRYPT_MODE, publ);
I then ran this loop:
System.out.println(cipher.doFinal());
int i;
for(i=0;i<3;i++){
byte[] mb=cipher.doFinal(ls[i].getBytes());
BigInteger m=new BigInteger(mb);
System.out.println(ls[i]); System.out.println(mb); System.out.println(m);}
System.out.println(i);
When the full code is run, it outputs random results, despite me specifying a specific key and no extra randomness.
An example result I get:
65537
8876876877514683419701394775736891208848228258165890045890388820357265315302111630148566347729740003117740265768481144604003358339087090263495975493871517
8876876877514683419701394775736891208848228258165890045890388820357265315302111630148566347729740003117740265768481144604003358339087090263495975493871517
[B#4dcbadb4
Abc
[B#4e515669
-5462094712561744024560535444520088624777610175171976781234077640626971429079045151098460959562949209262068937820990160757259828914166157234608976597064350
abc
[B#17d10166
3107323907558141358810822022103673043984543035554223372765982648017786708913920092191193838772862316322034375980838715614109687358524365202642588530273930
a
[B#1b9e1916
6445163883197255205896338963911279787620368657249049376589703029248914873890907191971001889147477506682665011145469994788929208061633206661616367855217482
3
Another example when running the same code:
65537
8876876877514683419701394775736891208848228258165890045890388820357265315302111630148566347729740003117740265768481144604003358339087090263495975493871517
8876876877514683419701394775736891208848228258165890045890388820357265315302111630148566347729740003117740265768481144604003358339087090263495975493871517
[B#61e4705b
Abc
[B#50134894
2417384835689897675160227748639975454110518566516301711167733068619357149939147252927780753402294448641286117754069483471011084747372041883630633605894839
abc
[B#2957fcb0
3879287039536019818188188335652449442503231260096157847006548762163832071824706188511894185312719300152349914092885760207457631282795049343998798324887051
a
[B#1376c05c
2592101622106234263448104107242829911318871603007110808578463097621588022744826051145004666578077234156235426617805240679356193746126406311247530120779148
3
I would expect both of these results to be the same. Please explain what is happening and how I should obtain the desired result.
Full code:
import java.math.BigInteger;
import java.security.*;
import java.security.interfaces.RSAPublicKey;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.crypto.*;
import java.util.Scanner;
import java.security.spec.*;
public class Test {
public static void main(String[] args) throws IOException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidKeySpecException {
String[] ls= {"Abc","abc","a"};
BigInteger N=new BigInteger("8876876877514683419701394775736891208848228258165890045890388820357265315302111630148566347729740003117740265768481144604003358339087090263495975493871517",10);
RSAPublicKeySpec pub=new RSAPublicKeySpec(N, new BigInteger("65537"));
Cipher cipher= Cipher.getInstance("RSA");
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPublicKey publ=(RSAPublicKey) keyFactory.generatePublic(pub);
System.out.println(publ.getPublicExponent());System.out.println(publ.getModulus());System.out.println(N);
cipher.init(Cipher.ENCRYPT_MODE, publ);
System.out.println(cipher.doFinal());
int i;
for(i=0;i<3;i++){
byte[] mb=cipher.doFinal(ls[i].getBytes());
BigInteger m=new BigInteger(mb);//Another error that was found later was that mb was being interpreted as a signed value.
System.out.println(ls[i]);System.out.println(mb);System.out.println(m);}
System.out.println(i);
}
}

Retrieving CMSSignedData from ASN.1 encoding in Bouncy Castle

In the following piece of code I sign a message using Bouncy Castle:
import org.bouncycastle.cms.CMSProcessableByteArray;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.CMSSignedDataGenerator;
import org.bouncycastle.cms.CMSTypedData;
import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
import org.bouncycastle.util.encoders.Base64;
import java.io.FileInputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.Security;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.PKCS8EncodedKeySpec;
public class Sign {
public static void main(String[] args) throws Exception {
Security.addProvider(new BouncyCastleProvider());
String certPath = "certPath";
FileInputStream inPublic = new FileInputStream(certPath);
CertificateFactory factory = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) factory.generateCertificate(inPublic);
String keyPrivatePath = "keyPath";
Path path = Paths.get(keyPrivatePath);
Files.readAllBytes(Paths.get(keyPrivatePath));
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(Files.readAllBytes(Paths.get(keyPrivatePath)));
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey privateKey = kf.generatePrivate(spec);
CMSProcessableByteArray msg = new CMSProcessableByteArray("My message".getBytes());
CMSSignedDataGenerator sGen = new CMSSignedDataGenerator();
ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(privateKey);
sGen.addSignerInfoGenerator(
new JcaSignerInfoGeneratorBuilder(
new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()
).build(sha1Signer, cert)
);
CMSSignedData sd = sGen.generate(msg);
CMSTypedData cmsBytes = new CMSProcessableByteArray(sd.getEncoded());
// How to reconstruct a CMSSignedData from cmsBytes again?
byte[] bytes = (byte[]) cmsBytes.getContent();
CMSSignedData retrieved = new CMSSignedData(bytes);
System.out.println(retrieved.getSignedContent()); // Doesn't work, is null
}
}
My question is how to retrieve the original CMSSignedData (wanting to read the original message, and verify it), using only the byte array of the ASN.1 encoding of this object.
The reason I am asking this, is that I want to decrypt a certain encrypted and signed message. I am able to decrypt this message, but it results in an ASN.1 encoded byte array (which does correspond to my original message), but I am not able to process this decrypted message any further.
You can use the classes org.bouncycastle.asn1.cms.ContentInfo and org.bouncycastle.asn1.ASN1Sequence:
CMSTypedData cmsBytes = new CMSProcessableByteArray(sd.getEncoded());
byte[] bytes = (byte[]) cmsBytes.getContent();
// reconstruct CMSSignedData from the byte array
ContentInfo ci = ContentInfo.getInstance(ASN1Sequence.fromByteArray(bytes));
CMSSignedData sig = new CMSSignedData(ci);
Also note that you must create a CMSSignedData with the content encapsulated in the signature, so you must change this:
CMSSignedData sd = sGen.generate(msg);
To this:
CMSSignedData sd = sGen.generate(msg, true);

Got "data isn't an object ID (tag = 49)" while generating X509 cert

I'm trying to generate my own CSR for my keystore, but it didn't go well and that error is confusing me. Here is my code:
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.X500NameBuilder;
import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.openssl.PEMWriter;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder;
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;
public class CreateKeyTest {
public static void main(String[] args) throws OperatorCreationException, IOException, GeneralSecurityException {
KeyPairGenerator kpg;
KeyPair kp;
RSAPublicKey pubKey;
RSAPrivateKey privKey;
FileOutputStream out;
KeyStore ks;
FileInputStream in;
FileInputStream bFis;
try {
ks = KeyStore.getInstance("JKS");
kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024);
kp = kpg.generateKeyPair();
pubKey = (RSAPublicKey) kp.getPublic();
privKey = (RSAPrivateKey) kp.getPrivate();
// generate CSR
ContentSigner sign = new JcaContentSignerBuilder("SHA1withRSA").build(privKey);
X500NameBuilder nBuilder = new X500NameBuilder();
nBuilder.addRDN(BCStyle.CN, "TestCSR");
nBuilder.addRDN(BCStyle.C, "ER");
nBuilder.addRDN(BCStyle.E, "test#test.com");
X500Name name = nBuilder.build();
PKCS10CertificationRequestBuilder cerReq = new JcaPKCS10CertificationRequestBuilder(name, pubKey);
PKCS10CertificationRequest request = cerReq.build(sign);
PEMWriter pWr = new PEMWriter(new FileWriter(new File("D:\\test.csr")));
pWr.writeObject(request);
pWr.flush();
pWr.close();
bFis = new FileInputStream("D:\\test.csr");
BufferedInputStream ksbufin = new BufferedInputStream(bFis);
X509Certificate certificate = (X509Certificate) CertificateFactory.getInstance("X.509")
.generateCertificate(ksbufin);
ks.setKeyEntry("RSA_key", kp.getPrivate(), "changeit".toCharArray(),
new java.security.cert.Certificate[] { certificate });
out = new FileOutputStream("key.store");
ks.store(out, "changeit".toCharArray());
System.out.println("New Keystore Generated");
out.close();
} catch (KeyStoreException | IOException | CertificateException | NoSuchAlgorithmException
| OperatorCreationException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
When I execute it, it showed me the exception:X509.ObjectIdentifier() -- data isn't an object ID (tag = 49), and it could be back-traced to generateCertificate(ksbufin). But I checked test.cer and it do have certificate data in there, and that exception message confused me, don't even know what does that mean(object ID? tag = 49? I didn't see I generated an ID in my code.).
Can anyone help me out this mud?
The error message is correct, test.csr does not contain a certificate. You have built it using a PKCS10CertificationRequest, so it consenquently contains a Certificate Signing Request (CSR).
You have generated a key pair, private and public, and a CSR. The CSR is a request of a certificate to a Certification Authority (CA). It contains the public key and some expected attributes for the certificate (CN, C, OU, etc). CSR is signed with the private key and has to be sent to CA. The CA will extract the public key, generates a certificate and signs it. See Certificate enrollment process
If you want a Certificate, you need to get signed the certificate by the CA

by which i can replace AES/ECB/PKCS5Padding for security concern in android application?

In my IDE warning displayed as Potentially insecure random numbers on Android 4.3 and older.
Read Android Development Blog for more info
how to make it secure?
package com.example.encryptographytest;
import java.security.Security;
import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String key = "1234567891234567";
String data = "example";
Log.d("CRYPTO-TEST", ""+ decrypt(encrypt(data, key), key));
Log.d("CRYPTO-TEST", ""+encrypt(data, key));
}
public static String encrypt(String input, String key){
byte[] crypted = null;
try{
SecretKeySpec skey = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skey);
crypted = cipher.doFinal(input.getBytes());
}catch(Exception e){
System.out.println(e.toString());
}
return new String(Base64.encode(crypted, Base64.DEFAULT));
// return new String(Base64.encodeBase64(crypted));
}
public static String decrypt(String input, String key){
byte[] output = null;
try{
SecretKeySpec skey = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, skey);
output = cipher.doFinal( Base64.decode(input, Base64.DEFAULT));
}catch(Exception e){
System.out.println(e.toString());
}
return new String(output);
}
}
First off, Android 4.3 is inherently not secure. There are now multiple exploits including remote ones such as StageFright.
Second, I assume you were talking about some-securerandom-thoughts.html, as your link was dead. It's talking about random number generations, but I don't see that in your code. Instead I see AES encryption, which isn't random at all.
Also, looking at Potentially insecure random numbers on Android 4.3 and older, this warning may have been related to a previous version of your code, which relied on SecureRandom to initialize the KeyGenerator.
Doing a google search for 'aes not secure' brings up all bunch of results and opinions, but it seems secure enough for most people.
Having said that, doing a google for 'ecb not secure' brings up Why shouldn't I use ECB encryption?, which aptly demonstrates why it's not secure. But that's not secure on any platform, not just Android 4.3.
Hope this helps and please clarify if the warning really came from this code snippet or specify the exact line.

Flexiprovider elliptic curve public key from byte array

I'm using the FlexiEC provider to generate an elliptic curve public key. Then I convert the key into a byte array. After that I want to get an instance of this public key from this byte array. Whenever I do this I get an exception.
The code is as follows:
import java.security.KeyPair;
import java.security.KeyFactory;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import javax.crypto.Cipher;
import de.flexiprovider.common.ies.IESParameterSpec;
import de.flexiprovider.core.FlexiCoreProvider;
import de.flexiprovider.ec.FlexiECProvider;
import de.flexiprovider.ec.parameters.CurveParams;
import de.flexiprovider.ec.parameters.CurveRegistry.BrainpoolP160r1;
import de.flexiprovider.pki.X509EncodedKeySpec;
[...]
KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECIES", "FlexiEC");
CurveParams ecParams = new BrainpoolP160r1();
kpg.initialize(ecParams, new SecureRandom());
KeyPair keyPair = kpg.generateKeyPair();
byte[] pubKey = keyPair.getPublic().getEncoded();
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(pubKey);
KeyFactory keyFactory = KeyFactory.getInstance("ECIES", "FlexiEC");
PublicKey pk = keyFactory.generatePublic(pubKeySpec);
The exception is:
Exception in thread "main" de.flexiprovider.api.exceptions.InvalidKeySpecException: java.lang.RuntimeException: java.security.InvalidAlgorithmParameterException: Caught IOException("Unknown named curve: 1.3.36.3.3.2.8.1.1.1")
at de.flexiprovider.ec.keys.ECKeyFactory.generatePublic(ECKeyFactory.java:205)
at de.flexiprovider.api.keys.KeyFactory.engineGeneratePublic(KeyFactory.java:39)
at java.security.KeyFactory.generatePublic(KeyFactory.java:328)
at com.test.App.test(App.java:68)
at com.test.App.main(App.java:76)
How can I recover the key correctly from the byte array?
I have some "ECIES", "FlexiEC" code which may be of reference for you. Here is the link:
BadPaddingException: invalid ciphertext
If this helps, the credit goes to owlstead who answered the question for me which enabled me to complete the implementation.

Categories