From a9c0b369cd23fc26ee3b0454f02c4b9e06c49913 Mon Sep 17 00:00:00 2001 From: EricJohnEastwood Date: Tue, 31 Aug 2021 22:17:23 +0530 Subject: [PATCH 01/27] Load dagger --- client/build.gradle | 2 +- client/clientmanager/build.gradle | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/client/build.gradle b/client/build.gradle index 90c880c8b..262612aff 100644 --- a/client/build.gradle +++ b/client/build.gradle @@ -5,7 +5,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:4.2.1' + classpath 'com.android.tools.build:gradle:7.0.1' // NOTE: Do not place your application dependencies here; they belong diff --git a/client/clientmanager/build.gradle b/client/clientmanager/build.gradle index e9c815d98..0b311ec53 100644 --- a/client/clientmanager/build.gradle +++ b/client/clientmanager/build.gradle @@ -9,8 +9,6 @@ android { defaultConfig { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode rootProject.ext.clientmanagerLibVersionCode - versionName rootProject.ext.clientmanagerLibVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles "consumer-rules.pro" @@ -29,7 +27,8 @@ android { } dependencies { - + implementation 'com.google.dagger:dagger:2.38.1' + annotationProcessor 'com.google.dagger:dagger-compiler:2.38.1' implementation 'androidx.appcompat:appcompat:1.3.1' implementation 'com.google.android.material:material:1.4.0' testImplementation "junit:junit:$rootProject.ext.junitVersion" From 49f8e25304a4db88233739fb448a80e4b8bafaf3 Mon Sep 17 00:00:00 2001 From: EricJohnEastwood Date: Wed, 1 Sep 2021 19:26:05 +0530 Subject: [PATCH 02/27] Implement DTOs --- client/clientmanager/build.gradle | 9 +++ .../dto/crypto/CryptoRequestDto.java | 14 ++++ .../dto/crypto/CryptoResponseDto.java | 8 +++ .../dto/crypto/PublicKeyRequestDto.java | 11 +++ .../dto/crypto/PublicKeyResponseDto.java | 9 +++ .../dto/crypto/SignRequestDto.java | 11 +++ .../dto/crypto/SignResponseDto.java | 9 +++ .../dto/crypto/SignVerifyRequestDto.java | 17 +++++ .../dto/crypto/SignVerifyResponseDto.java | 8 +++ .../crypto/LocalClientCryptoServiceImpl.java | 72 +++++++++++++++++++ 10 files changed, 168 insertions(+) diff --git a/client/clientmanager/build.gradle b/client/clientmanager/build.gradle index 0b311ec53..95a7de5b2 100644 --- a/client/clientmanager/build.gradle +++ b/client/clientmanager/build.gradle @@ -28,7 +28,16 @@ android { dependencies { implementation 'com.google.dagger:dagger:2.38.1' + implementation 'com.google.dagger:dagger-android-support:2.38.1' annotationProcessor 'com.google.dagger:dagger-compiler:2.38.1' + annotationProcessor 'com.google.dagger:dagger-android-processor:2.38.1' + + compileOnly 'org.projectlombok:lombok:1.18.20' + annotationProcessor 'org.projectlombok:lombok:1.18.20' + + implementation 'javax.validation:validation-api:2.0.0.Final' + + implementation 'androidx.appcompat:appcompat:1.3.1' implementation 'com.google.android.material:material:1.4.0' testImplementation "junit:junit:$rootProject.ext.junitVersion" diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/CryptoRequestDto.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/CryptoRequestDto.java index c0746ebe6..94bc3d506 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/CryptoRequestDto.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/CryptoRequestDto.java @@ -1,4 +1,18 @@ package io.mosip.registration.clientmanager.dto.crypto; +import javax.validation.constraints.NotBlank; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor public class CryptoRequestDto { + @NotBlank(message = "Invalid Request") + private String value; + + @NotBlank(message = "Invalid Request") + private String publicKey; } diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/CryptoResponseDto.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/CryptoResponseDto.java index 3959457fb..e2618f596 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/CryptoResponseDto.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/CryptoResponseDto.java @@ -1,4 +1,12 @@ package io.mosip.registration.clientmanager.dto.crypto; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor public class CryptoResponseDto { + private String value; } diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/PublicKeyRequestDto.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/PublicKeyRequestDto.java index 96d06d47d..7a4966fed 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/PublicKeyRequestDto.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/PublicKeyRequestDto.java @@ -1,4 +1,15 @@ package io.mosip.registration.clientmanager.dto.crypto; +import javax.validation.constraints.NotBlank; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor public class PublicKeyRequestDto { + @NotBlank(message = "Invalid Request") + String serverProfile; } diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/PublicKeyResponseDto.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/PublicKeyResponseDto.java index d95f34c0f..cfddbcb07 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/PublicKeyResponseDto.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/PublicKeyResponseDto.java @@ -1,4 +1,13 @@ package io.mosip.registration.clientmanager.dto.crypto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor public class PublicKeyResponseDto { + private String publicKey; } diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/SignRequestDto.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/SignRequestDto.java index f2842cd2b..11a5623cb 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/SignRequestDto.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/SignRequestDto.java @@ -1,4 +1,15 @@ package io.mosip.registration.clientmanager.dto.crypto; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import javax.validation.constraints.NotBlank; + +@Data +@AllArgsConstructor +@NoArgsConstructor public class SignRequestDto { + @NotBlank(message = "Invalid Request") + private String data; + } diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/SignResponseDto.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/SignResponseDto.java index e83c7a554..1ac9b3996 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/SignResponseDto.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/SignResponseDto.java @@ -1,4 +1,13 @@ package io.mosip.registration.clientmanager.dto.crypto; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + + +@Data +@AllArgsConstructor +@NoArgsConstructor public class SignResponseDto { + private String data; } diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/SignVerifyRequestDto.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/SignVerifyRequestDto.java index 0738c1060..2d8106891 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/SignVerifyRequestDto.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/SignVerifyRequestDto.java @@ -1,4 +1,21 @@ package io.mosip.registration.clientmanager.dto.crypto; +import javax.validation.constraints.NotBlank; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor public class SignVerifyRequestDto { + @NotBlank(message = "Invalid Request") + private String data; + + @NotBlank(message = "Invalid Request") + private String signature; + + @NotBlank(message = "Invalid Request") + private String publicKey; } diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/SignVerifyResponseDto.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/SignVerifyResponseDto.java index ddf26f368..3e5990988 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/SignVerifyResponseDto.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/SignVerifyResponseDto.java @@ -1,4 +1,12 @@ package io.mosip.registration.clientmanager.dto.crypto; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor public class SignVerifyResponseDto { + private boolean verified; } diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java index 638d2d076..518a0029e 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java @@ -1,28 +1,100 @@ package io.mosip.registration.clientmanager.service.crypto; +import android.content.Context; + +import java.security.*; +import javax.crypto.Cipher; +import javax.inject.Singleton; + import io.mosip.registration.clientmanager.dto.crypto.*; import io.mosip.registration.clientmanager.spi.crypto.ClientCryptoManagerService; +import io.mosip.registration.clientmanager.util.ConfigService; +@Singleton public class LocalClientCryptoServiceImpl implements ClientCryptoManagerService { + private static String ALGORITHM ; + private static int KEY_LENGTH; + private static String SIGN_ALGORITHM; + private static String PRIVATE_KEY; + private static String PUBLIC_KEY; + LocalClientCryptoServiceImpl() { + // get context from main activity + + } + + private void initializeClientSecurity() { + } @Override public SignResponseDto sign(SignRequestDto signRequestDto) { +// byte[] message; +// PrivateKey key; +// Signature s = null; +// try { +// s = Signature.getInstance("SHA256withRSA"); +// } catch (NoSuchAlgorithmException e) { +// e.printStackTrace(); +// } +// s.initSign(key); +// s.update(message); +// byte[] signature = s.sign(); return null; } @Override public SignVerifyResponseDto verifySign(SignVerifyRequestDto signVerifyRequestDto) { +// byte[] message; +// byte[] signature; +// PublicKey key; +// Signature s = null; +// try { +// s = Signature.getInstance("SHA256withRSA"); +// } catch (NoSuchAlgorithmException e) { +// e.printStackTrace(); +// } +// s.initVerify(key); +// s.update(message); +// boolean valid = s.verify(signature); return null; } @Override public CryptoResponseDto encrypt(CryptoRequestDto cryptoRequestDto) { +// byte[] message; +// byte[] signature; +// Signature sign = Signature.getInstance("SHA256withRSA"); +// +// //Creating KeyPair generator object +// KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA"); +// +// //Initializing the key pair generator +// keyPairGen.initialize(2048); +// +// //Generate the pair of keys +// KeyPair pair = keyPairGen.generateKeyPair(); +// +// //Getting the public key from the key pair +// PublicKey publicKey = pair.getPublic(); +// +// //Creating a Cipher object +// Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); +// +// //Initializing a Cipher object +// cipher.init(Cipher.ENCRYPT_MODE, publicKey); +// +// //Add data to the cipher +// byte[] input = "Welcome to Tutorialspoint".getBytes(); +// cipher.update(input); +// +// //encrypting the data +// byte[] cipherText = cipher.doFinal(); return null; } @Override public CryptoResponseDto decrypt(CryptoRequestDto cryptoRequestDto) { + return null; } From 2078083652144fccf141ba6a400593c3a4d1bb18 Mon Sep 17 00:00:00 2001 From: EricJohnEastwood Date: Thu, 2 Sep 2021 11:51:46 +0530 Subject: [PATCH 03/27] Implement Sign --- .../mosip/registration/app/MainActivity.java | 2 + .../crypto/LocalClientCryptoServiceImpl.java | 133 +++++++++++++++--- 2 files changed, 119 insertions(+), 16 deletions(-) diff --git a/client/app/src/main/java/io/mosip/registration/app/MainActivity.java b/client/app/src/main/java/io/mosip/registration/app/MainActivity.java index 0a53d264a..ea30641b2 100644 --- a/client/app/src/main/java/io/mosip/registration/app/MainActivity.java +++ b/client/app/src/main/java/io/mosip/registration/app/MainActivity.java @@ -5,6 +5,8 @@ import android.os.Bundle; import android.view.View; +import io.mosip.registration.clientmanager.service.crypto.LocalClientCryptoServiceImpl; + public class MainActivity extends AppCompatActivity { @Override diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java index 518a0029e..05bab7627 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java @@ -1,9 +1,32 @@ package io.mosip.registration.clientmanager.service.crypto; +import android.app.Service; import android.content.Context; +import android.content.Intent; +import android.os.Binder; +import android.os.Bundle; +import android.os.IBinder; +import androidx.annotation.Nullable; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.InetAddress; +import java.nio.file.Files; +import java.nio.file.Paths; import java.security.*; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; +import java.util.Base64.Decoder; +import java.util.Base64.Encoder; +import java.util.Objects; + import javax.crypto.Cipher; +import javax.inject.Inject; import javax.inject.Singleton; import io.mosip.registration.clientmanager.dto.crypto.*; @@ -11,34 +34,76 @@ import io.mosip.registration.clientmanager.util.ConfigService; @Singleton -public class LocalClientCryptoServiceImpl implements ClientCryptoManagerService { - private static String ALGORITHM ; +public class LocalClientCryptoServiceImpl extends Service implements ClientCryptoManagerService { + + private static Context context; + private static String ALGORITHM; private static int KEY_LENGTH; private static String SIGN_ALGORITHM; - private static String PRIVATE_KEY; - private static String PUBLIC_KEY; + private static String PRIVATE_KEY = "reg.key"; + private static String PUBLIC_KEY = "reg.pub"; + private static Encoder base64encoder; + private static Decoder base64decoder; + + @Inject LocalClientCryptoServiceImpl() { - // get context from main activity + try { + if (!doesKeysExists()) { + setupKeysDir(); + KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance(ALGORITHM); + keyGenerator.initialize(KEY_LENGTH, new SecureRandom()); + KeyPair keypair = keyGenerator.generateKeyPair(); + createKeyFile(PRIVATE_KEY, keypair.getPrivate().getEncoded()); + createKeyFile(PUBLIC_KEY, keypair.getPublic().getEncoded()); + } + } catch (Exception ex) { + ex.printStackTrace(); + } } + @Nullable + @Override + public IBinder onBind(Intent intent) { + return null; + } + private void initializeClientSecurity() { + // get context from main activity + Context context = getApplicationContext(); + ALGORITHM = ConfigService.getProperty("mosip.kernel.keygenerator.asymmetric-algorithm-name",context); + KEY_LENGTH = Integer.parseInt(ConfigService.getProperty("mosip.kernel.keygenerator.asymmetric-key-length",context)); + SIGN_ALGORITHM = ConfigService.getProperty("mosip.kernel.certificate.sign.algorithm", context); + base64encoder = Base64.getEncoder(); + base64decoder = Base64.getDecoder(); + + + } @Override public SignResponseDto sign(SignRequestDto signRequestDto) { -// byte[] message; -// PrivateKey key; -// Signature s = null; -// try { -// s = Signature.getInstance("SHA256withRSA"); -// } catch (NoSuchAlgorithmException e) { -// e.printStackTrace(); -// } -// s.initSign(key); -// s.update(message); -// byte[] signature = s.sign(); + byte[] dataToSign = base64decoder.decode(signRequestDto.getData()); + try { + Signature sign = Signature.getInstance(SIGN_ALGORITHM); + sign.initSign(getPrivateKey()); + + try(ByteArrayInputStream in = new ByteArrayInputStream(dataToSign)) { + byte[] buffer = new byte[2048]; + int len = 0; + while((len = in.read(buffer)) != -1) { + sign.update(buffer, 0, len); + } + byte[] signedData = sign.sign(); + + SignResponseDto signResponseDto = new SignResponseDto(); + signResponseDto.setData(base64encoder.encodeToString(signedData)); + return signResponseDto; + } + } catch (Exception ex) { + ex.printStackTrace(); + } return null; } @@ -102,4 +167,40 @@ public CryptoResponseDto decrypt(CryptoRequestDto cryptoRequestDto) { public PublicKeyResponseDto getPublicKey(PublicKeyRequestDto publicKeyRequestDto) { return null; } + + private void setupKeysDir() { + File keysDir = new File(getKeysDirPath()); + keysDir.mkdirs(); + } + + private boolean doesKeysExists() { + File keysDir = new File(getKeysDirPath()); + return (keysDir.exists() && Objects.requireNonNull(keysDir.list()).length >= 2); + } + + private String getKeysDirPath() { + return System.getProperty("user.dir") + File.separator + ".mosipkeys"; + } + + private void createKeyFile(String fileName, byte[] key) throws IOException { + try(FileOutputStream os = + new FileOutputStream(getKeysDirPath() + File.separator + fileName)) { + os.write(key); + } + } + + private PrivateKey getPrivateKey() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { + byte[] key = Files.readAllBytes(Paths.get(getKeysDirPath() + File.separator + PRIVATE_KEY)); + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(key); + KeyFactory kf = KeyFactory.getInstance(ALGORITHM); + return kf.generatePrivate(keySpec); + } + + private PublicKey getPublicKey() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { + byte[] key = Files.readAllBytes(Paths.get(getKeysDirPath() + File.separator + PUBLIC_KEY)); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(key); + KeyFactory kf = KeyFactory.getInstance(ALGORITHM); + return kf.generatePublic(keySpec); + } + } From fda12095399983ba3f82eeec65cce4c4c41cb0db Mon Sep 17 00:00:00 2001 From: EricJohnEastwood Date: Thu, 2 Sep 2021 12:19:05 +0530 Subject: [PATCH 04/27] Implement verifySign --- .../crypto/LocalClientCryptoServiceImpl.java | 49 +++++++++++++------ 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java index 05bab7627..a01e2fc99 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java @@ -85,6 +85,7 @@ private void initializeClientSecurity() { @Override public SignResponseDto sign(SignRequestDto signRequestDto) { byte[] dataToSign = base64decoder.decode(signRequestDto.getData()); + SignResponseDto signResponseDto = new SignResponseDto(); try { Signature sign = Signature.getInstance(SIGN_ALGORITHM); sign.initSign(getPrivateKey()); @@ -97,31 +98,47 @@ public SignResponseDto sign(SignRequestDto signRequestDto) { } byte[] signedData = sign.sign(); - SignResponseDto signResponseDto = new SignResponseDto(); + signResponseDto.setData(base64encoder.encodeToString(signedData)); - return signResponseDto; + } } catch (Exception ex) { ex.printStackTrace(); } - return null; + return signResponseDto; } @Override public SignVerifyResponseDto verifySign(SignVerifyRequestDto signVerifyRequestDto) { -// byte[] message; -// byte[] signature; -// PublicKey key; -// Signature s = null; -// try { -// s = Signature.getInstance("SHA256withRSA"); -// } catch (NoSuchAlgorithmException e) { -// e.printStackTrace(); -// } -// s.initVerify(key); -// s.update(message); -// boolean valid = s.verify(signature); - return null; + boolean result = false; + SignVerifyResponseDto signVerifyResponseDto = new SignVerifyResponseDto(); + try { + byte[] public_key = base64decoder.decode(signVerifyRequestDto.getPublicKey()); + byte[] signature = base64decoder.decode(signVerifyRequestDto.getSignature()); + byte[] actualData = base64decoder.decode(signVerifyRequestDto.getData()); + + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(public_key); + KeyFactory kf = KeyFactory.getInstance(ALGORITHM); + PublicKey publicKey = kf.generatePublic(keySpec); + + Signature sign = Signature.getInstance(SIGN_ALGORITHM); + sign.initVerify(publicKey); + + try(ByteArrayInputStream in = new ByteArrayInputStream(actualData)) { + byte[] buffer = new byte[2048]; + int len = 0; + + while((len = in.read(buffer)) != -1) { + sign.update(buffer, 0, len); + } + result = sign.verify(signature); + } + signVerifyResponseDto.setVerified(result); + } + catch(Exception ex) { + ex.printStackTrace(); + } + return signVerifyResponseDto; } @Override From 1fade3b112f2945d043220a104a94edb833d27b7 Mon Sep 17 00:00:00 2001 From: EricJohnEastwood Date: Fri, 3 Sep 2021 13:56:10 +0530 Subject: [PATCH 05/27] Implement encrypt --- .../crypto/LocalClientCryptoServiceImpl.java | 230 ++++++++++-------- 1 file changed, 126 insertions(+), 104 deletions(-) diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java index a01e2fc99..811e620bc 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java @@ -6,6 +6,8 @@ import android.os.Binder; import android.os.Bundle; import android.os.IBinder; +import android.security.keystore.KeyGenParameterSpec; +import android.security.keystore.KeyProperties; import androidx.annotation.Nullable; @@ -16,16 +18,34 @@ import java.net.InetAddress; import java.nio.file.Files; import java.nio.file.Paths; -import java.security.*; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.Signature; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; +import java.util.Arrays; import java.util.Base64; import java.util.Base64.Decoder; import java.util.Base64.Encoder; import java.util.Objects; +import javax.crypto.BadPaddingException; import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.KeyGenerator; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.spec.GCMParameterSpec; +import javax.crypto.spec.SecretKeySpec; import javax.inject.Inject; import javax.inject.Singleton; @@ -36,32 +56,35 @@ @Singleton public class LocalClientCryptoServiceImpl extends Service implements ClientCryptoManagerService { - private static Context context; - private static String ALGORITHM; - private static int KEY_LENGTH; - private static String SIGN_ALGORITHM; - private static String PRIVATE_KEY = "reg.key"; - private static String PUBLIC_KEY = "reg.pub"; + private Context context; + private static Encoder base64encoder; private static Decoder base64decoder; + private static String CRYPTO_ASYMMETRIC_ALGORITHM; + private static String CRYPTO_SYMMETRIC_ALGORITHM; + private static String KEYGEN_ASYMMETRIC_ALGORITHM; + private static String KEYGEN_SYMMETRIC_ALGORITHM; + private static int KEYGEN_ASYMMETRIC_KEY_LENGTH; + private static int KEYGEN_SYMMETRIC_KEY_LENGTH; + private static int CRYPTO_GCM_TAG_LENGTH; + private static final int IV_LENGTH = 12; + private static final int AAD_LENGTH = 32; + private static String CRYPTO_HASH_ALGORITHM; + private static int CRYPTO_HASH_SYMMETRIC_KEY_LENGTH; + private static int CRYPTO_HASH_ITERATION; + private static String CRYPTO_SIGN_ALGORITHM; + private static String CERTIFICATE_SIGN_ALGORITHM; + + private static final String ANDROID_KEY_STORE = "AndroidKeyStore"; + private static final String ALIAS = "DUMMY_ALIAS"; + + private static SecureRandom secureRandom = null; + @Inject LocalClientCryptoServiceImpl() { - try { - if (!doesKeysExists()) { - setupKeysDir(); - KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance(ALGORITHM); - keyGenerator.initialize(KEY_LENGTH, new SecureRandom()); - KeyPair keypair = keyGenerator.generateKeyPair(); - createKeyFile(PRIVATE_KEY, keypair.getPrivate().getEncoded()); - createKeyFile(PUBLIC_KEY, keypair.getPublic().getEncoded()); - } - } catch (Exception ex) { - ex.printStackTrace(); - } - } @Nullable @@ -73,9 +96,25 @@ public IBinder onBind(Intent intent) { private void initializeClientSecurity() { // get context from main activity Context context = getApplicationContext(); - ALGORITHM = ConfigService.getProperty("mosip.kernel.keygenerator.asymmetric-algorithm-name",context); - KEY_LENGTH = Integer.parseInt(ConfigService.getProperty("mosip.kernel.keygenerator.asymmetric-key-length",context)); - SIGN_ALGORITHM = ConfigService.getProperty("mosip.kernel.certificate.sign.algorithm", context); + this.context = context; + CRYPTO_ASYMMETRIC_ALGORITHM = ConfigService.getProperty("mosip.kernel.crypto.asymmetric-algorithm-name",context); + CRYPTO_SYMMETRIC_ALGORITHM = ConfigService.getProperty("mosip.kernel.crypto.symmetric-algorithm-name",context); + KEYGEN_ASYMMETRIC_ALGORITHM = ConfigService.getProperty("mosip.kernel.keygenerator.asymmetric-algorithm-name",context); + KEYGEN_SYMMETRIC_ALGORITHM = ConfigService.getProperty("mosip.kernel.keygenerator.symmetric-algorithm-name",context); + KEYGEN_ASYMMETRIC_KEY_LENGTH = Integer.parseInt( + ConfigService.getProperty("mosip.kernel.keygenerator.asymmetric-key-length",context)); + KEYGEN_SYMMETRIC_KEY_LENGTH = Integer.parseInt( + ConfigService.getProperty("mosip.kernel.keygenerator.symmetric-key-length",context)); + CRYPTO_GCM_TAG_LENGTH = Integer.parseInt( + ConfigService.getProperty("mosip.kernel.crypto.gcm-tag-length",context)); + CRYPTO_HASH_ALGORITHM = ConfigService.getProperty("mosip.kernel.crypto.hash-algorithm-name",context); + CRYPTO_HASH_SYMMETRIC_KEY_LENGTH = Integer.parseInt( + ConfigService.getProperty("mosip.kernel.crypto.hash-symmetric-key-length",context)); + CRYPTO_HASH_ITERATION = Integer.parseInt( + ConfigService.getProperty("mosip.kernel.crypto.hash-iteration",context)); + CRYPTO_SIGN_ALGORITHM = ConfigService.getProperty("mosip.kernel.crypto.sign-algorithm-name",context); + CERTIFICATE_SIGN_ALGORITHM = ConfigService.getProperty("mosip.kernel.certificate.sign.algorithm",context); + base64encoder = Base64.getEncoder(); base64decoder = Base64.getDecoder(); @@ -87,30 +126,26 @@ public SignResponseDto sign(SignRequestDto signRequestDto) { byte[] dataToSign = base64decoder.decode(signRequestDto.getData()); SignResponseDto signResponseDto = new SignResponseDto(); try { - Signature sign = Signature.getInstance(SIGN_ALGORITHM); - sign.initSign(getPrivateKey()); +// read private key from keystore + PrivateKey privateKey = getPrivateKey(); - try(ByteArrayInputStream in = new ByteArrayInputStream(dataToSign)) { - byte[] buffer = new byte[2048]; - int len = 0; - while((len = in.read(buffer)) != -1) { - sign.update(buffer, 0, len); - } - byte[] signedData = sign.sign(); + Signature sign = Signature.getInstance(CRYPTO_SIGN_ALGORITHM); + sign.initSign(privateKey); + sign.update(dataToSign); + byte[] signedData = sign.sign(); + signResponseDto.setData(base64encoder.encodeToString(signedData)); + return signResponseDto; - signResponseDto.setData(base64encoder.encodeToString(signedData)); - - } } catch (Exception ex) { ex.printStackTrace(); } - return signResponseDto; + return null; } @Override public SignVerifyResponseDto verifySign(SignVerifyRequestDto signVerifyRequestDto) { - boolean result = false; + SignVerifyResponseDto signVerifyResponseDto = new SignVerifyResponseDto(); try { byte[] public_key = base64decoder.decode(signVerifyRequestDto.getPublicKey()); @@ -118,59 +153,48 @@ public SignVerifyResponseDto verifySign(SignVerifyRequestDto signVerifyRequestDt byte[] actualData = base64decoder.decode(signVerifyRequestDto.getData()); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(public_key); - KeyFactory kf = KeyFactory.getInstance(ALGORITHM); + KeyFactory kf = KeyFactory.getInstance(KEYGEN_ASYMMETRIC_ALGORITHM); PublicKey publicKey = kf.generatePublic(keySpec); - Signature sign = Signature.getInstance(SIGN_ALGORITHM); + Signature sign = Signature.getInstance(CRYPTO_SIGN_ALGORITHM); sign.initVerify(publicKey); + sign.update(actualData); + boolean result = sign.verify(signature); - try(ByteArrayInputStream in = new ByteArrayInputStream(actualData)) { - byte[] buffer = new byte[2048]; - int len = 0; - - while((len = in.read(buffer)) != -1) { - sign.update(buffer, 0, len); - } - result = sign.verify(signature); - } signVerifyResponseDto.setVerified(result); + return signVerifyResponseDto; } catch(Exception ex) { ex.printStackTrace(); } - return signVerifyResponseDto; + return null; } @Override public CryptoResponseDto encrypt(CryptoRequestDto cryptoRequestDto) { -// byte[] message; -// byte[] signature; -// Signature sign = Signature.getInstance("SHA256withRSA"); -// -// //Creating KeyPair generator object -// KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA"); -// -// //Initializing the key pair generator -// keyPairGen.initialize(2048); -// -// //Generate the pair of keys -// KeyPair pair = keyPairGen.generateKeyPair(); -// -// //Getting the public key from the key pair -// PublicKey publicKey = pair.getPublic(); -// -// //Creating a Cipher object -// Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); -// -// //Initializing a Cipher object -// cipher.init(Cipher.ENCRYPT_MODE, publicKey); -// -// //Add data to the cipher -// byte[] input = "Welcome to Tutorialspoint".getBytes(); -// cipher.update(input); -// -// //encrypting the data -// byte[] cipherText = cipher.doFinal(); + CryptoResponseDto cryptoResponseDto = new CryptoResponseDto(); + + try { + byte[] publicKey = base64decoder.decode(cryptoRequestDto.getPublicKey()); + byte[] dataToEncrypt = base64decoder.decode(cryptoRequestDto.getValue()); + // read secret key from keystore + SecretKey secretKey = getSecretKey(); + + + final Cipher cipher = Cipher.getInstance(CRYPTO_SYMMETRIC_ALGORITHM); + cipher.init(Cipher.ENCRYPT_MODE, getSecretKey()); + + byte[] iv = cipher.getIV(); + + byte[] encryption = cipher.doFinal(dataToEncrypt)); + + + cryptoResponseDto.setValue(base64encoder.encodeToString(encryption)); + return cryptoResponseDto; + } catch(Exception ex) { + ex.printStackTrace(); + } + return null; } @@ -185,39 +209,37 @@ public PublicKeyResponseDto getPublicKey(PublicKeyRequestDto publicKeyRequestDto return null; } - private void setupKeysDir() { - File keysDir = new File(getKeysDirPath()); - keysDir.mkdirs(); - } + private static SecretKey getSecretKey() throws NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException { + final KeyGenerator keyGenerator = KeyGenerator + .getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE); - private boolean doesKeysExists() { - File keysDir = new File(getKeysDirPath()); - return (keysDir.exists() && Objects.requireNonNull(keysDir.list()).length >= 2); - } + keyGenerator.init(new KeyGenParameterSpec.Builder(ALIAS, + KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) + .setBlockModes(KeyProperties.BLOCK_MODE_GCM) + .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) + .build()); - private String getKeysDirPath() { - return System.getProperty("user.dir") + File.separator + ".mosipkeys"; + return keyGenerator.generateKey(); } - private void createKeyFile(String fileName, byte[] key) throws IOException { - try(FileOutputStream os = - new FileOutputStream(getKeysDirPath() + File.separator + fileName)) { - os.write(key); - } - } - private PrivateKey getPrivateKey() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { - byte[] key = Files.readAllBytes(Paths.get(getKeysDirPath() + File.separator + PRIVATE_KEY)); - PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(key); - KeyFactory kf = KeyFactory.getInstance(ALGORITHM); - return kf.generatePrivate(keySpec); + // Setup Keystore + private void setupKeys() throws NoSuchProviderException, NoSuchAlgorithmException { + final KeyGenerator keyGenerator = KeyGenerator + .getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE); + final KeyGenParameterSpec keyGenParameterSpec = new KeyGenParameterSpec.Builder(ALIAS, + KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) + .setBlockModes(KeyProperties.BLOCK_MODE_GCM) + .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) + .build(); } - private PublicKey getPublicKey() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { - byte[] key = Files.readAllBytes(Paths.get(getKeysDirPath() + File.separator + PUBLIC_KEY)); - X509EncodedKeySpec keySpec = new X509EncodedKeySpec(key); - KeyFactory kf = KeyFactory.getInstance(ALGORITHM); - return kf.generatePublic(keySpec); - } + private static byte[] generateRandomBytes(int length) { + if(secureRandom == null) + secureRandom = new SecureRandom(); + byte[] bytes = new byte[length]; + secureRandom.nextBytes(bytes); + return bytes; + } } From 941efd040d805777064ab8b0645c7ff60507394a Mon Sep 17 00:00:00 2001 From: EricJohnEastwood Date: Fri, 3 Sep 2021 13:58:00 +0530 Subject: [PATCH 06/27] Implement encrypt --- .../service/crypto/LocalClientCryptoServiceImpl.java | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java index 811e620bc..c3c4fb3e5 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java @@ -223,17 +223,6 @@ private static SecretKey getSecretKey() throws NoSuchProviderException, NoSuchAl } - // Setup Keystore - private void setupKeys() throws NoSuchProviderException, NoSuchAlgorithmException { - final KeyGenerator keyGenerator = KeyGenerator - .getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE); - final KeyGenParameterSpec keyGenParameterSpec = new KeyGenParameterSpec.Builder(ALIAS, - KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) - .setBlockModes(KeyProperties.BLOCK_MODE_GCM) - .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) - .build(); - } - private static byte[] generateRandomBytes(int length) { if(secureRandom == null) secureRandom = new SecureRandom(); From f59bcda2acc21af895a932e5514768ec7d5a1a3e Mon Sep 17 00:00:00 2001 From: EricJohnEastwood Date: Fri, 3 Sep 2021 21:40:29 +0530 Subject: [PATCH 07/27] Implement encrypt --- .../crypto/LocalClientCryptoServiceImpl.java | 124 +++++++++++++----- 1 file changed, 88 insertions(+), 36 deletions(-) diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java index c3c4fb3e5..e5b534025 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java @@ -12,6 +12,7 @@ import androidx.annotation.Nullable; import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -23,14 +24,19 @@ import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; +import java.security.KeyStore; +import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Signature; +import java.security.UnrecoverableEntryException; +import java.security.cert.CertificateException; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.RSAKeyGenParameterSpec; import java.security.spec.X509EncodedKeySpec; import java.util.Arrays; import java.util.Base64; @@ -45,6 +51,7 @@ import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.spec.GCMParameterSpec; +import javax.crypto.spec.OAEPParameterSpec; import javax.crypto.spec.SecretKeySpec; import javax.inject.Inject; import javax.inject.Singleton; @@ -77,7 +84,8 @@ public class LocalClientCryptoServiceImpl extends Service implements ClientCrypt private static String CERTIFICATE_SIGN_ALGORITHM; private static final String ANDROID_KEY_STORE = "AndroidKeyStore"; - private static final String ALIAS = "DUMMY_ALIAS"; + private static final String PRIVATE_ALIAS = "PRIVATE_ALIAS"; + private static final String SECRET_ALIAS = "SECRET_ALIAS"; private static SecureRandom secureRandom = null; @@ -85,6 +93,40 @@ public class LocalClientCryptoServiceImpl extends Service implements ClientCrypt @Inject LocalClientCryptoServiceImpl() { + Context context = getApplicationContext(); + this.context = context; + try { + KeyPairGenerator kpg = KeyPairGenerator.getInstance( + KEYGEN_ASYMMETRIC_ALGORITHM, ANDROID_KEY_STORE); + kpg.initialize(new KeyGenParameterSpec.Builder( + PRIVATE_ALIAS, + KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY | + KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) + .setKeySize(KEYGEN_ASYMMETRIC_KEY_LENGTH) + .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512) + .build()); + + KeyPair kp = kpg.generateKeyPair(); + } catch(Exception ex) { + ex.printStackTrace(); + } + try { + KeyGenerator kg = KeyGenerator + .getInstance(KEYGEN_SYMMETRIC_ALGORITHM, ANDROID_KEY_STORE); + + final KeyGenParameterSpec keyGenParameterSpec = new KeyGenParameterSpec.Builder(SECRET_ALIAS, + KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) + .setBlockModes(KeyProperties.BLOCK_MODE_GCM) + .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7) + .setKeySize(KEYGEN_SYMMETRIC_KEY_LENGTH) + .build(); + + kg.init(keyGenParameterSpec); + SecretKey secretKey = kg.generateKey(); + + } catch(Exception ex) { + ex.printStackTrace(); + } } @Nullable @@ -95,8 +137,7 @@ public IBinder onBind(Intent intent) { private void initializeClientSecurity() { // get context from main activity - Context context = getApplicationContext(); - this.context = context; + CRYPTO_ASYMMETRIC_ALGORITHM = ConfigService.getProperty("mosip.kernel.crypto.asymmetric-algorithm-name",context); CRYPTO_SYMMETRIC_ALGORITHM = ConfigService.getProperty("mosip.kernel.crypto.symmetric-algorithm-name",context); KEYGEN_ASYMMETRIC_ALGORITHM = ConfigService.getProperty("mosip.kernel.keygenerator.asymmetric-algorithm-name",context); @@ -123,10 +164,10 @@ private void initializeClientSecurity() { } @Override public SignResponseDto sign(SignRequestDto signRequestDto) { - byte[] dataToSign = base64decoder.decode(signRequestDto.getData()); SignResponseDto signResponseDto = new SignResponseDto(); + + byte[] dataToSign = base64decoder.decode(signRequestDto.getData()); try { -// read private key from keystore PrivateKey privateKey = getPrivateKey(); Signature sign = Signature.getInstance(CRYPTO_SIGN_ALGORITHM); @@ -145,13 +186,12 @@ public SignResponseDto sign(SignRequestDto signRequestDto) { @Override public SignVerifyResponseDto verifySign(SignVerifyRequestDto signVerifyRequestDto) { - SignVerifyResponseDto signVerifyResponseDto = new SignVerifyResponseDto(); - try { - byte[] public_key = base64decoder.decode(signVerifyRequestDto.getPublicKey()); - byte[] signature = base64decoder.decode(signVerifyRequestDto.getSignature()); - byte[] actualData = base64decoder.decode(signVerifyRequestDto.getData()); + byte[] public_key = base64decoder.decode(signVerifyRequestDto.getPublicKey()); + byte[] signature = base64decoder.decode(signVerifyRequestDto.getSignature()); + byte[] actualData = base64decoder.decode(signVerifyRequestDto.getData()); + try { X509EncodedKeySpec keySpec = new X509EncodedKeySpec(public_key); KeyFactory kf = KeyFactory.getInstance(KEYGEN_ASYMMETRIC_ALGORITHM); PublicKey publicKey = kf.generatePublic(keySpec); @@ -174,22 +214,33 @@ public SignVerifyResponseDto verifySign(SignVerifyRequestDto signVerifyRequestDt public CryptoResponseDto encrypt(CryptoRequestDto cryptoRequestDto) { CryptoResponseDto cryptoResponseDto = new CryptoResponseDto(); + byte[] public_key = base64decoder.decode(cryptoRequestDto.getPublicKey()); + byte[] dataToEncrypt = base64decoder.decode(cryptoRequestDto.getValue()); try { - byte[] publicKey = base64decoder.decode(cryptoRequestDto.getPublicKey()); - byte[] dataToEncrypt = base64decoder.decode(cryptoRequestDto.getValue()); - // read secret key from keystore - SecretKey secretKey = getSecretKey(); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(public_key); + KeyFactory kf = KeyFactory.getInstance(KEYGEN_ASYMMETRIC_ALGORITHM); + PublicKey publicKey = kf.generatePublic(keySpec); + SecretKey secretKey = getSecretKey(); - final Cipher cipher = Cipher.getInstance(CRYPTO_SYMMETRIC_ALGORITHM); - cipher.init(Cipher.ENCRYPT_MODE, getSecretKey()); + final Cipher cipher_symmetric = Cipher.getInstance(CRYPTO_SYMMETRIC_ALGORITHM); + cipher_symmetric.init(Cipher.ENCRYPT_MODE, secretKey); + byte[] iv = cipher_symmetric.getIV(); + byte[] data_encryption = cipher_symmetric.doFinal(dataToEncrypt); - byte[] iv = cipher.getIV(); + final Cipher cipher_asymmetric = Cipher.getInstance(CRYPTO_ASYMMETRIC_ALGORITHM); + cipher_asymmetric.init(Cipher.ENCRYPT_MODE, publicKey); + byte[] key_encryption = cipher_asymmetric.doFinal(secretKey.getEncoded()); - byte[] encryption = cipher.doFinal(dataToEncrypt)); + // store iv and encryption in encrypted_data + ByteArrayOutputStream outputStream = new ByteArrayOutputStream( ); + outputStream.write(key_encryption); + outputStream.write(iv); + outputStream.write(data_encryption); + byte encrypted_key_iv_data[] = outputStream.toByteArray(); - cryptoResponseDto.setValue(base64encoder.encodeToString(encryption)); + cryptoResponseDto.setValue(base64encoder.encodeToString(encrypted_key_iv_data)); return cryptoResponseDto; } catch(Exception ex) { ex.printStackTrace(); @@ -209,26 +260,27 @@ public PublicKeyResponseDto getPublicKey(PublicKeyRequestDto publicKeyRequestDto return null; } - private static SecretKey getSecretKey() throws NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException { - final KeyGenerator keyGenerator = KeyGenerator - .getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE); - - keyGenerator.init(new KeyGenParameterSpec.Builder(ALIAS, - KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) - .setBlockModes(KeyProperties.BLOCK_MODE_GCM) - .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) - .build()); + private SecretKey getSecretKey() throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableEntryException { + KeyStore ks = KeyStore.getInstance(ANDROID_KEY_STORE); + ks.load(null); + KeyStore.Entry entry = ks.getEntry(SECRET_ALIAS, null); + if (!(entry instanceof KeyStore.SecretKeyEntry)) { + return null; + } + return ((KeyStore.SecretKeyEntry) entry).getSecretKey(); + } - return keyGenerator.generateKey(); + private PrivateKey getPrivateKey() throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableEntryException { + KeyStore ks = KeyStore.getInstance(ANDROID_KEY_STORE); + ks.load(null); + KeyStore.Entry entry = ks.getEntry(PRIVATE_ALIAS, null); + if (!(entry instanceof KeyStore.PrivateKeyEntry)) { + return null; + } + return ((KeyStore.PrivateKeyEntry) entry).getPrivateKey(); } - private static byte[] generateRandomBytes(int length) { - if(secureRandom == null) - secureRandom = new SecureRandom(); - byte[] bytes = new byte[length]; - secureRandom.nextBytes(bytes); - return bytes; - } + } From d0c4d3c091b02510432184c41f37361dd91cc693 Mon Sep 17 00:00:00 2001 From: EricJohnEastwood Date: Fri, 3 Sep 2021 21:43:36 +0530 Subject: [PATCH 08/27] Initialize keystore --- .../service/crypto/LocalClientCryptoServiceImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java index e5b534025..040965a34 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java @@ -95,6 +95,7 @@ public class LocalClientCryptoServiceImpl extends Service implements ClientCrypt LocalClientCryptoServiceImpl() { Context context = getApplicationContext(); this.context = context; + initializeClientSecurity(); try { KeyPairGenerator kpg = KeyPairGenerator.getInstance( KEYGEN_ASYMMETRIC_ALGORITHM, ANDROID_KEY_STORE); From 48b9890520bfcbdb8ede9896590628b95ea0507e Mon Sep 17 00:00:00 2001 From: EricJohnEastwood Date: Fri, 3 Sep 2021 22:24:15 +0530 Subject: [PATCH 09/27] Implement decrypt --- .../crypto/LocalClientCryptoServiceImpl.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java index 040965a34..8bb757aae 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java @@ -252,7 +252,32 @@ public CryptoResponseDto encrypt(CryptoRequestDto cryptoRequestDto) { @Override public CryptoResponseDto decrypt(CryptoRequestDto cryptoRequestDto) { + CryptoResponseDto cryptoResponseDto = new CryptoResponseDto(); + byte[] dataToDecrypt = base64decoder.decode(cryptoRequestDto.getValue()); + byte[] public_key = base64decoder.decode(cryptoRequestDto.getPublicKey()); + + byte[] encryptedSecretKey = Arrays.copyOfRange(dataToDecrypt, 0, KEYGEN_SYMMETRIC_KEY_LENGTH); + byte[] iv = Arrays.copyOfRange(dataToDecrypt, KEYGEN_SYMMETRIC_KEY_LENGTH, KEYGEN_SYMMETRIC_KEY_LENGTH+IV_LENGTH); + byte[] encrypted_data = Arrays.copyOfRange(dataToDecrypt, KEYGEN_SYMMETRIC_KEY_LENGTH+IV_LENGTH, dataToDecrypt.length); + + try { + PrivateKey privateKey = getPrivateKey(); + final Cipher cipher_asymmetric = Cipher.getInstance(CRYPTO_ASYMMETRIC_ALGORITHM); + cipher_asymmetric.init(Cipher.DECRYPT_MODE, privateKey); + byte[] secretKeyBytes = cipher_asymmetric.doFinal(encryptedSecretKey); + + SecretKey secretKey = new SecretKeySpec(secretKeyBytes, KEYGEN_SYMMETRIC_ALGORITHM); + final Cipher cipher_symmetric = Cipher.getInstance(CRYPTO_SYMMETRIC_ALGORITHM); + final GCMParameterSpec spec = new GCMParameterSpec(CRYPTO_GCM_TAG_LENGTH, iv); + cipher_symmetric.init(Cipher.DECRYPT_MODE, secretKey, spec); + String decrypted_data = base64encoder.encodeToString(cipher_symmetric.doFinal(encrypted_data)); + + cryptoResponseDto.setValue(decrypted_data); + return cryptoResponseDto; + } catch(Exception ex) { + ex.printStackTrace(); + } return null; } From e718ddad9c54353a5177837201dff1d99b85be94 Mon Sep 17 00:00:00 2001 From: EricJohnEastwood Date: Sat, 4 Sep 2021 11:55:32 +0530 Subject: [PATCH 10/27] Add AAD --- .../crypto/LocalClientCryptoServiceImpl.java | 110 ++++++++++++++---- 1 file changed, 87 insertions(+), 23 deletions(-) diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java index 8bb757aae..606dee1eb 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java @@ -44,6 +44,10 @@ import java.util.Base64.Encoder; import java.util.Objects; +import java.lang.*; +import java.security.SecureRandom; +import java.util.Random; + import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; @@ -65,18 +69,32 @@ public class LocalClientCryptoServiceImpl extends Service implements ClientCrypt private Context context; + // encoder and decoder from java itself private static Encoder base64encoder; private static Decoder base64decoder; + + // asymmetric encryption details together----------------------------- private static String CRYPTO_ASYMMETRIC_ALGORITHM; - private static String CRYPTO_SYMMETRIC_ALGORITHM; private static String KEYGEN_ASYMMETRIC_ALGORITHM; - private static String KEYGEN_SYMMETRIC_ALGORITHM; + private static String KEYGEN_ASYMMETRIC_ALGO_BLOCK; + private static String KEYGEN_ASYMMETRIC_ALGO_PAD; private static int KEYGEN_ASYMMETRIC_KEY_LENGTH; + + // symmetric encryption details together----------------------------- + private static String CRYPTO_SYMMETRIC_ALGORITHM; + private static String KEYGEN_SYMMETRIC_ALGORITHM; + private static String KEYGEN_SYMMETRIC_ALGO_BLOCK; + private static String KEYGEN_SYMMETRIC_ALGO_PAD; private static int KEYGEN_SYMMETRIC_KEY_LENGTH; + private static int CRYPTO_GCM_TAG_LENGTH; - private static final int IV_LENGTH = 12; - private static final int AAD_LENGTH = 32; + + + // need to read aad and iv length from config files----- + private static int IV_LENGTH = 12; + private static int AAD_LENGTH = 32; + private static String CRYPTO_HASH_ALGORITHM; private static int CRYPTO_HASH_SYMMETRIC_KEY_LENGTH; private static int CRYPTO_HASH_ITERATION; @@ -96,38 +114,66 @@ public class LocalClientCryptoServiceImpl extends Service implements ClientCrypt Context context = getApplicationContext(); this.context = context; initializeClientSecurity(); - try { - KeyPairGenerator kpg = KeyPairGenerator.getInstance( - KEYGEN_ASYMMETRIC_ALGORITHM, ANDROID_KEY_STORE); - kpg.initialize(new KeyGenParameterSpec.Builder( - PRIVATE_ALIAS, - KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY | - KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) - .setKeySize(KEYGEN_ASYMMETRIC_KEY_LENGTH) - .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512) - .build()); - KeyPair kp = kpg.generateKeyPair(); - } catch(Exception ex) { - ex.printStackTrace(); - } + + // hardcoding some initializations for now + // for symmetric encryption---------------------------------------------------------- + + // first set the encruption algorithm variables like blocks,padding,key length etc.....should be originally from the config file + // NOTE:CURRENTLY HARDCODED + // [ + KEYGEN_SYMMETRIC_ALGO_BLOCK=KeyProperties.BLOCK_MODE_GCM; + KEYGEN_SYMMETRIC_ALGO_PAD=KeyProperties.ENCRYPTION_PADDING_PKCS7; + // ] + try { KeyGenerator kg = KeyGenerator .getInstance(KEYGEN_SYMMETRIC_ALGORITHM, ANDROID_KEY_STORE); final KeyGenParameterSpec keyGenParameterSpec = new KeyGenParameterSpec.Builder(SECRET_ALIAS, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) - .setBlockModes(KeyProperties.BLOCK_MODE_GCM) - .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7) + .setBlockModes(KEYGEN_SYMMETRIC_ALGO_BLOCK) + .setEncryptionPaddings(KEYGEN_SYMMETRIC_ALGO_PAD) .setKeySize(KEYGEN_SYMMETRIC_KEY_LENGTH) .build(); kg.init(keyGenParameterSpec); - SecretKey secretKey = kg.generateKey(); + SecretKey secretKey = kg.generateKey(); } catch(Exception ex) { ex.printStackTrace(); } + + // for assymetric encruption storing keypair--------------------------- + //set the asymmetric encruption algorithm variables like blocks,padding,key length etc.....should be originally from the config file + // NOTE:CURRENTLY HARDCODED + // [ + KEYGEN_ASYMMETRIC_ALGO_BLOCK=KeyProperties.BLOCK_MODE_ECB; + KEYGEN_ASYMMETRIC_ALGO_PAD=KeyProperties.ENCRYPTION_PADDING_RSA_OAEP; + // ] + + try { + // lot of errors in assymetric part + KeyPairGenerator kpg = KeyPairGenerator.getInstance( + KEYGEN_ASYMMETRIC_ALGORITHM, ANDROID_KEY_STORE); + + // after creating keypairgenerator,instead of again creating KeyGenParameterSpec,creating inside parameter for initialize itslef- + // ----------------------------------- + + kpg.initialize(new KeyGenParameterSpec.Builder( + PRIVATE_ALIAS, + KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY | + KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) + .setBlockModes(KEYGEN_ASYMMETRIC_ALGO_BLOCK) + .setKeySize(KEYGEN_ASYMMETRIC_KEY_LENGTH) + .setEncryptionPaddings(KEYGEN_ASYMMETRIC_ALGO_PAD) + .setDigests(KeyProperties.DIGEST_SHA256) + .build()); + + KeyPair kp = kpg.generateKeyPair(); + } catch(Exception ex) { + ex.printStackTrace(); + } } @Nullable @@ -224,20 +270,24 @@ public CryptoResponseDto encrypt(CryptoRequestDto cryptoRequestDto) { SecretKey secretKey = getSecretKey(); + // symmetric encryption of data----------------------------------------------------- final Cipher cipher_symmetric = Cipher.getInstance(CRYPTO_SYMMETRIC_ALGORITHM); cipher_symmetric.init(Cipher.ENCRYPT_MODE, secretKey); byte[] iv = cipher_symmetric.getIV(); byte[] data_encryption = cipher_symmetric.doFinal(dataToEncrypt); + + // asymmetric encryption of secret key---------------------------------------------------- final Cipher cipher_asymmetric = Cipher.getInstance(CRYPTO_ASYMMETRIC_ALGORITHM); cipher_asymmetric.init(Cipher.ENCRYPT_MODE, publicKey); byte[] key_encryption = cipher_asymmetric.doFinal(secretKey.getEncoded()); - // store iv and encryption in encrypted_data + // storing iv and encryption in encrypted_data ByteArrayOutputStream outputStream = new ByteArrayOutputStream( ); outputStream.write(key_encryption); outputStream.write(iv); outputStream.write(data_encryption); + // need to add aad byte encrypted_key_iv_data[] = outputStream.toByteArray(); @@ -262,12 +312,15 @@ public CryptoResponseDto decrypt(CryptoRequestDto cryptoRequestDto) { try { PrivateKey privateKey = getPrivateKey(); + + // asymmetric decryption of secret key---------------------------------------------------- final Cipher cipher_asymmetric = Cipher.getInstance(CRYPTO_ASYMMETRIC_ALGORITHM); cipher_asymmetric.init(Cipher.DECRYPT_MODE, privateKey); byte[] secretKeyBytes = cipher_asymmetric.doFinal(encryptedSecretKey); SecretKey secretKey = new SecretKeySpec(secretKeyBytes, KEYGEN_SYMMETRIC_ALGORITHM); + // symmetric decryption of data----------------------------------------------------- final Cipher cipher_symmetric = Cipher.getInstance(CRYPTO_SYMMETRIC_ALGORITHM); final GCMParameterSpec spec = new GCMParameterSpec(CRYPTO_GCM_TAG_LENGTH, iv); cipher_symmetric.init(Cipher.DECRYPT_MODE, secretKey, spec); @@ -286,6 +339,7 @@ public PublicKeyResponseDto getPublicKey(PublicKeyRequestDto publicKeyRequestDto return null; } + // get secret key from keystore private SecretKey getSecretKey() throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableEntryException { KeyStore ks = KeyStore.getInstance(ANDROID_KEY_STORE); ks.load(null); @@ -296,6 +350,7 @@ private SecretKey getSecretKey() throws KeyStoreException, CertificateException, return ((KeyStore.SecretKeyEntry) entry).getSecretKey(); } + // get private key from keystore private PrivateKey getPrivateKey() throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableEntryException { KeyStore ks = KeyStore.getInstance(ANDROID_KEY_STORE); ks.load(null); @@ -306,7 +361,16 @@ private PrivateKey getPrivateKey() throws KeyStoreException, CertificateExceptio return ((KeyStore.PrivateKeyEntry) entry).getPrivateKey(); } + // random byte generation for AAD + public static byte[] generateRandomBytes(int length) { + + SecureRandom secureRandom = new SecureRandom(); + + byte[] bytes = new byte[length]; + secureRandom.nextBytes(bytes); + return bytes; + } -} +} \ No newline at end of file From f10b48056775ad0bf6e45a0e779b45004fc1fb92 Mon Sep 17 00:00:00 2001 From: EricJohnEastwood Date: Sat, 4 Sep 2021 12:29:01 +0530 Subject: [PATCH 11/27] Implement AAD --- .../crypto/LocalClientCryptoServiceImpl.java | 124 +++++++++++------- 1 file changed, 79 insertions(+), 45 deletions(-) diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java index 606dee1eb..2afd4d850 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java @@ -59,6 +59,7 @@ import javax.crypto.spec.SecretKeySpec; import javax.inject.Inject; import javax.inject.Singleton; +import javax.security.cert.Certificate; import io.mosip.registration.clientmanager.dto.crypto.*; import io.mosip.registration.clientmanager.spi.crypto.ClientCryptoManagerService; @@ -116,10 +117,48 @@ public class LocalClientCryptoServiceImpl extends Service implements ClientCrypt initializeClientSecurity(); + genSecretKey(); + genPrivPubKey(); + + + } + + @Nullable + @Override + public IBinder onBind(Intent intent) { + return null; + } + + private void initializeClientSecurity() { + // get context from main activity + + CRYPTO_ASYMMETRIC_ALGORITHM = ConfigService.getProperty("mosip.kernel.crypto.asymmetric-algorithm-name",context); + CRYPTO_SYMMETRIC_ALGORITHM = ConfigService.getProperty("mosip.kernel.crypto.symmetric-algorithm-name",context); + KEYGEN_ASYMMETRIC_ALGORITHM = ConfigService.getProperty("mosip.kernel.keygenerator.asymmetric-algorithm-name",context); + KEYGEN_SYMMETRIC_ALGORITHM = ConfigService.getProperty("mosip.kernel.keygenerator.symmetric-algorithm-name",context); + KEYGEN_ASYMMETRIC_KEY_LENGTH = Integer.parseInt( + ConfigService.getProperty("mosip.kernel.keygenerator.asymmetric-key-length",context)); + KEYGEN_SYMMETRIC_KEY_LENGTH = Integer.parseInt( + ConfigService.getProperty("mosip.kernel.keygenerator.symmetric-key-length",context)); + CRYPTO_GCM_TAG_LENGTH = Integer.parseInt( + ConfigService.getProperty("mosip.kernel.crypto.gcm-tag-length",context)); + CRYPTO_HASH_ALGORITHM = ConfigService.getProperty("mosip.kernel.crypto.hash-algorithm-name",context); + CRYPTO_HASH_SYMMETRIC_KEY_LENGTH = Integer.parseInt( + ConfigService.getProperty("mosip.kernel.crypto.hash-symmetric-key-length",context)); + CRYPTO_HASH_ITERATION = Integer.parseInt( + ConfigService.getProperty("mosip.kernel.crypto.hash-iteration",context)); + CRYPTO_SIGN_ALGORITHM = ConfigService.getProperty("mosip.kernel.crypto.sign-algorithm-name",context); + CERTIFICATE_SIGN_ALGORITHM = ConfigService.getProperty("mosip.kernel.certificate.sign.algorithm",context); + + base64encoder = Base64.getEncoder(); + base64decoder = Base64.getDecoder(); + } + + private void genSecretKey() { // hardcoding some initializations for now // for symmetric encryption---------------------------------------------------------- - // first set the encruption algorithm variables like blocks,padding,key length etc.....should be originally from the config file + // first set the encryption algorithm variables like blocks,padding,key length etc.....should be originally from the config file // NOTE:CURRENTLY HARDCODED // [ KEYGEN_SYMMETRIC_ALGO_BLOCK=KeyProperties.BLOCK_MODE_GCM; @@ -143,9 +182,11 @@ public class LocalClientCryptoServiceImpl extends Service implements ClientCrypt } catch(Exception ex) { ex.printStackTrace(); } + } - // for assymetric encruption storing keypair--------------------------- - //set the asymmetric encruption algorithm variables like blocks,padding,key length etc.....should be originally from the config file + private void genPrivPubKey() { + // for asymmetric encryption storing keypair--------------------------- + //set the asymmetric encryption algorithm variables like blocks,padding,key length etc.....should be originally from the config file // NOTE:CURRENTLY HARDCODED // [ KEYGEN_ASYMMETRIC_ALGO_BLOCK=KeyProperties.BLOCK_MODE_ECB; @@ -153,14 +194,11 @@ public class LocalClientCryptoServiceImpl extends Service implements ClientCrypt // ] try { - // lot of errors in assymetric part + // lot of errors in asymmetric part KeyPairGenerator kpg = KeyPairGenerator.getInstance( KEYGEN_ASYMMETRIC_ALGORITHM, ANDROID_KEY_STORE); - // after creating keypairgenerator,instead of again creating KeyGenParameterSpec,creating inside parameter for initialize itslef- - // ----------------------------------- - - kpg.initialize(new KeyGenParameterSpec.Builder( + final KeyGenParameterSpec keyPairGenParameterSpec = new KeyGenParameterSpec.Builder( PRIVATE_ALIAS, KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY | KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) @@ -168,7 +206,9 @@ public class LocalClientCryptoServiceImpl extends Service implements ClientCrypt .setKeySize(KEYGEN_ASYMMETRIC_KEY_LENGTH) .setEncryptionPaddings(KEYGEN_ASYMMETRIC_ALGO_PAD) .setDigests(KeyProperties.DIGEST_SHA256) - .build()); + .build(); + + kpg.initialize(keyPairGenParameterSpec); KeyPair kp = kpg.generateKeyPair(); } catch(Exception ex) { @@ -176,39 +216,6 @@ public class LocalClientCryptoServiceImpl extends Service implements ClientCrypt } } - @Nullable - @Override - public IBinder onBind(Intent intent) { - return null; - } - - private void initializeClientSecurity() { - // get context from main activity - - CRYPTO_ASYMMETRIC_ALGORITHM = ConfigService.getProperty("mosip.kernel.crypto.asymmetric-algorithm-name",context); - CRYPTO_SYMMETRIC_ALGORITHM = ConfigService.getProperty("mosip.kernel.crypto.symmetric-algorithm-name",context); - KEYGEN_ASYMMETRIC_ALGORITHM = ConfigService.getProperty("mosip.kernel.keygenerator.asymmetric-algorithm-name",context); - KEYGEN_SYMMETRIC_ALGORITHM = ConfigService.getProperty("mosip.kernel.keygenerator.symmetric-algorithm-name",context); - KEYGEN_ASYMMETRIC_KEY_LENGTH = Integer.parseInt( - ConfigService.getProperty("mosip.kernel.keygenerator.asymmetric-key-length",context)); - KEYGEN_SYMMETRIC_KEY_LENGTH = Integer.parseInt( - ConfigService.getProperty("mosip.kernel.keygenerator.symmetric-key-length",context)); - CRYPTO_GCM_TAG_LENGTH = Integer.parseInt( - ConfigService.getProperty("mosip.kernel.crypto.gcm-tag-length",context)); - CRYPTO_HASH_ALGORITHM = ConfigService.getProperty("mosip.kernel.crypto.hash-algorithm-name",context); - CRYPTO_HASH_SYMMETRIC_KEY_LENGTH = Integer.parseInt( - ConfigService.getProperty("mosip.kernel.crypto.hash-symmetric-key-length",context)); - CRYPTO_HASH_ITERATION = Integer.parseInt( - ConfigService.getProperty("mosip.kernel.crypto.hash-iteration",context)); - CRYPTO_SIGN_ALGORITHM = ConfigService.getProperty("mosip.kernel.crypto.sign-algorithm-name",context); - CERTIFICATE_SIGN_ALGORITHM = ConfigService.getProperty("mosip.kernel.certificate.sign.algorithm",context); - - base64encoder = Base64.getEncoder(); - base64decoder = Base64.getDecoder(); - - - - } @Override public SignResponseDto sign(SignRequestDto signRequestDto) { SignResponseDto signResponseDto = new SignResponseDto(); @@ -274,6 +281,8 @@ public CryptoResponseDto encrypt(CryptoRequestDto cryptoRequestDto) { final Cipher cipher_symmetric = Cipher.getInstance(CRYPTO_SYMMETRIC_ALGORITHM); cipher_symmetric.init(Cipher.ENCRYPT_MODE, secretKey); byte[] iv = cipher_symmetric.getIV(); + byte[] aad = generateRandomBytes(AAD_LENGTH); + cipher_symmetric.updateAAD(aad); byte[] data_encryption = cipher_symmetric.doFinal(dataToEncrypt); @@ -286,6 +295,7 @@ public CryptoResponseDto encrypt(CryptoRequestDto cryptoRequestDto) { ByteArrayOutputStream outputStream = new ByteArrayOutputStream( ); outputStream.write(key_encryption); outputStream.write(iv); + outputStream.write(aad); outputStream.write(data_encryption); // need to add aad byte encrypted_key_iv_data[] = outputStream.toByteArray(); @@ -308,7 +318,8 @@ public CryptoResponseDto decrypt(CryptoRequestDto cryptoRequestDto) { byte[] encryptedSecretKey = Arrays.copyOfRange(dataToDecrypt, 0, KEYGEN_SYMMETRIC_KEY_LENGTH); byte[] iv = Arrays.copyOfRange(dataToDecrypt, KEYGEN_SYMMETRIC_KEY_LENGTH, KEYGEN_SYMMETRIC_KEY_LENGTH+IV_LENGTH); - byte[] encrypted_data = Arrays.copyOfRange(dataToDecrypt, KEYGEN_SYMMETRIC_KEY_LENGTH+IV_LENGTH, dataToDecrypt.length); + byte[] aad = Arrays.copyOfRange(dataToDecrypt,KEYGEN_SYMMETRIC_KEY_LENGTH+IV_LENGTH, KEYGEN_SYMMETRIC_KEY_LENGTH+IV_LENGTH+AAD_LENGTH); + byte[] encrypted_data = Arrays.copyOfRange(dataToDecrypt, KEYGEN_SYMMETRIC_KEY_LENGTH+IV_LENGTH+AAD_LENGTH, dataToDecrypt.length); try { PrivateKey privateKey = getPrivateKey(); @@ -322,8 +333,9 @@ public CryptoResponseDto decrypt(CryptoRequestDto cryptoRequestDto) { // symmetric decryption of data----------------------------------------------------- final Cipher cipher_symmetric = Cipher.getInstance(CRYPTO_SYMMETRIC_ALGORITHM); - final GCMParameterSpec spec = new GCMParameterSpec(CRYPTO_GCM_TAG_LENGTH, iv); - cipher_symmetric.init(Cipher.DECRYPT_MODE, secretKey, spec); + final GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(CRYPTO_GCM_TAG_LENGTH, iv); + cipher_symmetric.init(Cipher.DECRYPT_MODE, secretKey, gcmParameterSpec); + cipher_symmetric.updateAAD(aad); String decrypted_data = base64encoder.encodeToString(cipher_symmetric.doFinal(encrypted_data)); cryptoResponseDto.setValue(decrypted_data); @@ -336,6 +348,16 @@ public CryptoResponseDto decrypt(CryptoRequestDto cryptoRequestDto) { @Override public PublicKeyResponseDto getPublicKey(PublicKeyRequestDto publicKeyRequestDto) { + PublicKeyResponseDto publicKeyResponseDto = new PublicKeyResponseDto(); + + try { + PublicKey publicKey = getPublicKey(); + String public_key = base64encoder.encodeToString(publicKey.getEncoded()); + publicKeyResponseDto.setPublicKey(public_key); + return publicKeyResponseDto; + } catch(Exception ex) { + ex.printStackTrace(); + } return null; } @@ -361,6 +383,18 @@ private PrivateKey getPrivateKey() throws KeyStoreException, CertificateExceptio return ((KeyStore.PrivateKeyEntry) entry).getPrivateKey(); } + // get public key from keystore + private PublicKey getPublicKey() throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableEntryException { + KeyStore ks = KeyStore.getInstance(ANDROID_KEY_STORE); + ks.load(null); + KeyStore.Entry entry = ks.getEntry(PRIVATE_ALIAS, null); + if (!(entry instanceof KeyStore.PrivateKeyEntry)) { + return null; + } + + return ((KeyStore.PrivateKeyEntry) entry).getCertificate().getPublicKey(); + } + // random byte generation for AAD public static byte[] generateRandomBytes(int length) { From f88f330128429d5abb9e164c1556ef8ae4a1383c Mon Sep 17 00:00:00 2001 From: EricJohnEastwood Date: Sat, 11 Sep 2021 10:04:14 +0530 Subject: [PATCH 12/27] Construct Client Crypto Service --- client/app/src/main/AndroidManifest.xml | 3 + .../mosip/registration/app/MainActivity.java | 57 ++++++++++++ client/build.gradle | 2 +- .../crypto/LocalClientCryptoServiceImpl.java | 92 +++++++++++++------ 4 files changed, 124 insertions(+), 30 deletions(-) diff --git a/client/app/src/main/AndroidManifest.xml b/client/app/src/main/AndroidManifest.xml index d5adab468..44a6772cf 100644 --- a/client/app/src/main/AndroidManifest.xml +++ b/client/app/src/main/AndroidManifest.xml @@ -9,6 +9,7 @@ android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.registration_client"> + @@ -18,6 +19,8 @@ + + \ No newline at end of file diff --git a/client/app/src/main/java/io/mosip/registration/app/MainActivity.java b/client/app/src/main/java/io/mosip/registration/app/MainActivity.java index ea30641b2..e4244099b 100644 --- a/client/app/src/main/java/io/mosip/registration/app/MainActivity.java +++ b/client/app/src/main/java/io/mosip/registration/app/MainActivity.java @@ -2,20 +2,43 @@ import androidx.appcompat.app.AppCompatActivity; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; import android.os.Bundle; +import android.os.IBinder; import android.view.View; +import android.widget.Toast; import io.mosip.registration.clientmanager.service.crypto.LocalClientCryptoServiceImpl; public class MainActivity extends AppCompatActivity { + private static final String TAG = MainActivity.class.getSimpleName(); + + private LocalClientCryptoServiceImpl localClientCryptoService; + private boolean isServiceBound; + + + private Intent serviceIntent; + private ServiceConnection serviceConnection; + private boolean mStopLoop; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); + serviceIntent= new Intent(getApplicationContext(), LocalClientCryptoServiceImpl.class); + bindService(); } + public void click_start(View view) { + switch (view.getId()) { + + + } openStart(); } @@ -23,4 +46,38 @@ public void openStart() { OpenDialog od1 = new OpenDialog(); od1.show(getSupportFragmentManager(),"od1"); } + + private void bindService(){ + if(serviceConnection==null){ + serviceConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName className, + IBinder service) { + // Binding to LocalClientCryptoServiceImpl, cast the IBinder and + // getting LocalClientCryptoServiceImpl instance + LocalClientCryptoServiceImpl.ClientCryptoServiceBinder binder = + (LocalClientCryptoServiceImpl.ClientCryptoServiceBinder) service; + //Get instance of your service + localClientCryptoService = binder.getServiceInstance(); + isServiceBound = true; + } + + @Override + public void onServiceDisconnected(ComponentName arg0) { + isServiceBound = false; + } + }; + } + + bindService(serviceIntent,serviceConnection, Context.BIND_AUTO_CREATE); + + } + + private void unbindService(){ + if(isServiceBound){ + unbindService(serviceConnection); + isServiceBound=false; + } + } + } \ No newline at end of file diff --git a/client/build.gradle b/client/build.gradle index 262612aff..671cc7ac9 100644 --- a/client/build.gradle +++ b/client/build.gradle @@ -5,7 +5,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.0.1' + classpath 'com.android.tools.build:gradle:7.0.2' // NOTE: Do not place your application dependencies here; they belong diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java index 2afd4d850..6a2caea54 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java @@ -4,66 +4,52 @@ import android.content.Context; import android.content.Intent; import android.os.Binder; -import android.os.Bundle; import android.os.IBinder; import android.security.keystore.KeyGenParameterSpec; import android.security.keystore.KeyProperties; import androidx.annotation.Nullable; -import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; -import java.net.InetAddress; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Signature; import java.security.UnrecoverableEntryException; import java.security.cert.CertificateException; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.PKCS8EncodedKeySpec; -import java.security.spec.RSAKeyGenParameterSpec; import java.security.spec.X509EncodedKeySpec; import java.util.Arrays; import java.util.Base64; import java.util.Base64.Decoder; import java.util.Base64.Encoder; -import java.util.Objects; -import java.lang.*; -import java.security.SecureRandom; -import java.util.Random; - -import javax.crypto.BadPaddingException; import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; import javax.crypto.KeyGenerator; -import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.spec.GCMParameterSpec; -import javax.crypto.spec.OAEPParameterSpec; import javax.crypto.spec.SecretKeySpec; import javax.inject.Inject; import javax.inject.Singleton; -import javax.security.cert.Certificate; -import io.mosip.registration.clientmanager.dto.crypto.*; +import io.mosip.registration.clientmanager.dto.crypto.CryptoRequestDto; +import io.mosip.registration.clientmanager.dto.crypto.CryptoResponseDto; +import io.mosip.registration.clientmanager.dto.crypto.PublicKeyRequestDto; +import io.mosip.registration.clientmanager.dto.crypto.PublicKeyResponseDto; +import io.mosip.registration.clientmanager.dto.crypto.SignRequestDto; +import io.mosip.registration.clientmanager.dto.crypto.SignResponseDto; +import io.mosip.registration.clientmanager.dto.crypto.SignVerifyRequestDto; +import io.mosip.registration.clientmanager.dto.crypto.SignVerifyResponseDto; import io.mosip.registration.clientmanager.spi.crypto.ClientCryptoManagerService; import io.mosip.registration.clientmanager.util.ConfigService; +import android.util.Log; +import android.R; @Singleton public class LocalClientCryptoServiceImpl extends Service implements ClientCryptoManagerService { @@ -110,25 +96,73 @@ public class LocalClientCryptoServiceImpl extends Service implements ClientCrypt + // implementing service...extending binder + public class ClientCryptoServiceBinder extends Binder { + public LocalClientCryptoServiceImpl getServiceInstance(){ + return LocalClientCryptoServiceImpl.this; + } + } + + //creating instance of binder to be passed to MainActivity + private IBinder mBinder=new ClientCryptoServiceBinder(); + + @Inject LocalClientCryptoServiceImpl() { Context context = getApplicationContext(); this.context = context; initializeClientSecurity(); - genSecretKey(); genPrivPubKey(); - - } + // ON BIND BINDER FOR MAIN CLASS HERE @Nullable @Override public IBinder onBind(Intent intent) { - return null; + return mBinder; } + + // on start of service +// @Override +// public void onStart(Intent intent, int startId) { +// super.onStart(intent, startId); +// } + + // on start command +// @Override +// public int onStartCommand(Intent intent, int flags, int startId) { +// initializeClientSecurity(); +// +// stopSelf(); +// return START_STICKY; +// } + + + // onDestroy service + @Override + public void onDestroy() { + super.onDestroy(); +// any object to be destroyed should be destroyed here + } + + + // UNBIND METHOD + @Override + public boolean onUnbind(Intent intent) { + return super.onUnbind(intent); + } + + // REBIND + public void onRebind(Intent intent) { + super.onRebind(intent); + } + + + + private void initializeClientSecurity() { // get context from main activity @@ -298,7 +332,7 @@ public CryptoResponseDto encrypt(CryptoRequestDto cryptoRequestDto) { outputStream.write(aad); outputStream.write(data_encryption); // need to add aad - byte encrypted_key_iv_data[] = outputStream.toByteArray(); + byte[] encrypted_key_iv_data = outputStream.toByteArray(); cryptoResponseDto.setValue(base64encoder.encodeToString(encrypted_key_iv_data)); From 0057d075e046a64e21e01deaa10dd1dcc04ba28f Mon Sep 17 00:00:00 2001 From: EricJohnEastwood Date: Sat, 11 Sep 2021 13:08:10 +0530 Subject: [PATCH 13/27] Add initLocalClientCryptoService --- .../mosip/registration/app/MainActivity.java | 21 +++++++------- .../app/src/main/res/layout/activity_main.xml | 28 +++++++++++++------ .../crypto/LocalClientCryptoServiceImpl.java | 26 ++++++++++------- 3 files changed, 46 insertions(+), 29 deletions(-) diff --git a/client/app/src/main/java/io/mosip/registration/app/MainActivity.java b/client/app/src/main/java/io/mosip/registration/app/MainActivity.java index e4244099b..62bdea29c 100644 --- a/client/app/src/main/java/io/mosip/registration/app/MainActivity.java +++ b/client/app/src/main/java/io/mosip/registration/app/MainActivity.java @@ -9,6 +9,7 @@ import android.os.Bundle; import android.os.IBinder; import android.view.View; +import android.widget.TextView; import android.widget.Toast; import io.mosip.registration.clientmanager.service.crypto.LocalClientCryptoServiceImpl; @@ -24,29 +25,28 @@ public class MainActivity extends AppCompatActivity { private ServiceConnection serviceConnection; private boolean mStopLoop; + TextView textView; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); + textView = (TextView) findViewById(R.id.testerView); serviceIntent= new Intent(getApplicationContext(), LocalClientCryptoServiceImpl.class); bindService(); } - public void click_start(View view) { - switch (view.getId()) { - - - } - openStart(); + public void click_encrypt(View view) { + textView.setText("Clicked Encrypt"); } - public void openStart() { - OpenDialog od1 = new OpenDialog(); - od1.show(getSupportFragmentManager(),"od1"); + public void click_decrypt(View view) { + textView.setText("Clicked Decrypt"); } + private void bindService(){ if(serviceConnection==null){ serviceConnection = new ServiceConnection() { @@ -59,11 +59,12 @@ public void onServiceConnected(ComponentName className, (LocalClientCryptoServiceImpl.ClientCryptoServiceBinder) service; //Get instance of your service localClientCryptoService = binder.getServiceInstance(); + localClientCryptoService.initLocalClientCryptoService(); isServiceBound = true; } @Override - public void onServiceDisconnected(ComponentName arg0) { + public void onServiceDisconnected(ComponentName className) { isServiceBound = false; } }; diff --git a/client/app/src/main/res/layout/activity_main.xml b/client/app/src/main/res/layout/activity_main.xml index 3a0ed2641..08a9727ba 100644 --- a/client/app/src/main/res/layout/activity_main.xml +++ b/client/app/src/main/res/layout/activity_main.xml @@ -7,32 +7,31 @@ tools:context=".MainActivity"> + + \ No newline at end of file diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java index 6a2caea54..689003eeb 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java @@ -53,8 +53,8 @@ @Singleton public class LocalClientCryptoServiceImpl extends Service implements ClientCryptoManagerService { - - private Context context; + private static final String TAG = LocalClientCryptoServiceImpl.class.getSimpleName(); + private static Context context; // encoder and decoder from java itself private static Encoder base64encoder; @@ -106,15 +106,19 @@ public LocalClientCryptoServiceImpl getServiceInstance(){ //creating instance of binder to be passed to MainActivity private IBinder mBinder=new ClientCryptoServiceBinder(); - @Inject - LocalClientCryptoServiceImpl() { - Context context = getApplicationContext(); - this.context = context; + public LocalClientCryptoServiceImpl() { + Log.d(TAG, "LocalClientCryptoServiceImpl: Constructor call successful"); + } + + public void initLocalClientCryptoService() { + context = getApplicationContext(); initializeClientSecurity(); genSecretKey(); genPrivPubKey(); + + Log.d(TAG, "LocalClientCryptoServiceImpl: Initialization call successful"); } // ON BIND BINDER FOR MAIN CLASS HERE @@ -139,8 +143,6 @@ public IBinder onBind(Intent intent) { // stopSelf(); // return START_STICKY; // } - - // onDestroy service @Override public void onDestroy() { @@ -165,7 +167,7 @@ public void onRebind(Intent intent) { private void initializeClientSecurity() { // get context from main activity - + Log.d(TAG, "LocalClientCryptoServiceImpl: Initializating"); CRYPTO_ASYMMETRIC_ALGORITHM = ConfigService.getProperty("mosip.kernel.crypto.asymmetric-algorithm-name",context); CRYPTO_SYMMETRIC_ALGORITHM = ConfigService.getProperty("mosip.kernel.crypto.symmetric-algorithm-name",context); KEYGEN_ASYMMETRIC_ALGORITHM = ConfigService.getProperty("mosip.kernel.keygenerator.asymmetric-algorithm-name",context); @@ -213,6 +215,8 @@ private void genSecretKey() { kg.init(keyGenParameterSpec); SecretKey secretKey = kg.generateKey(); + Log.d(TAG, "LocalClientCryptoServiceImpl: Secret key generation successful"); + } catch(Exception ex) { ex.printStackTrace(); } @@ -243,8 +247,10 @@ private void genPrivPubKey() { .build(); kpg.initialize(keyPairGenParameterSpec); - KeyPair kp = kpg.generateKeyPair(); + + Log.d(TAG, "LocalClientCryptoServiceImpl: Private key generation successful"); + } catch(Exception ex) { ex.printStackTrace(); } From 8d86ba393f780bbb46e96a8c1401a423dcaa1ee3 Mon Sep 17 00:00:00 2001 From: EricJohnEastwood Date: Mon, 13 Sep 2021 14:07:36 +0530 Subject: [PATCH 14/27] Add secret key generation --- .../mosip/registration/app/MainActivity.java | 43 ++++++ .../src/main/AndroidManifest.xml | 1 - .../src/main/assets/config.properties | 2 +- .../crypto/LocalClientCryptoServiceImpl.java | 126 ++++++++++++++++-- 4 files changed, 158 insertions(+), 14 deletions(-) diff --git a/client/app/src/main/java/io/mosip/registration/app/MainActivity.java b/client/app/src/main/java/io/mosip/registration/app/MainActivity.java index 62bdea29c..7edea93aa 100644 --- a/client/app/src/main/java/io/mosip/registration/app/MainActivity.java +++ b/client/app/src/main/java/io/mosip/registration/app/MainActivity.java @@ -1,5 +1,6 @@ package io.mosip.registration.app; +import io.mosip.registration.clientmanager.dto.crypto.*; import androidx.appcompat.app.AppCompatActivity; import android.content.ComponentName; @@ -40,6 +41,48 @@ protected void onCreate(Bundle savedInstanceState) { public void click_encrypt(View view) { textView.setText("Clicked Encrypt"); + try{ + Thread.sleep(2000); + } catch(InterruptedException e){ + e.printStackTrace(); + } + new Thread(new Runnable() { + @Override + public void run() { + textView.setText("Starting encryption process"); +// creating public key request + PublicKeyRequestDto publicKeyRequestDto = new PublicKeyRequestDto(); + PublicKeyResponseDto publicKeyResponseDto = localClientCryptoService.getPublicKey(publicKeyRequestDto); +// PublicKeyResponseDto publicKeyResponseDto; + try{ + Thread.sleep(2000); + }catch(InterruptedException e){ + e.printStackTrace(); + } + textView.setText("Got public key..creating cryptoRequest"); + + CryptoRequestDto cryptoRequestDto = new CryptoRequestDto( + "message", publicKeyResponseDto.getPublicKey()); + + CryptoResponseDto cryptoResponseDto = localClientCryptoService.encrypt(cryptoRequestDto); + +// SignRequestDto signRequestDto = new SignRequestDto("dummy"); + + try{ + Thread.sleep(2000); + }catch(InterruptedException e){ + e.printStackTrace(); + } + + textView.setText("Encryption done"); + try{ + Thread.sleep(2000); + }catch(InterruptedException e) { + e.printStackTrace(); + } + textView.setText(cryptoResponseDto.getValue()); + } + }).start(); } public void click_decrypt(View view) { diff --git a/client/clientmanager/src/main/AndroidManifest.xml b/client/clientmanager/src/main/AndroidManifest.xml index fc8bce968..b14b0c1a6 100644 --- a/client/clientmanager/src/main/AndroidManifest.xml +++ b/client/clientmanager/src/main/AndroidManifest.xml @@ -1,5 +1,4 @@ - \ No newline at end of file diff --git a/client/clientmanager/src/main/assets/config.properties b/client/clientmanager/src/main/assets/config.properties index 2561f023a..ea25bdeb4 100644 --- a/client/clientmanager/src/main/assets/config.properties +++ b/client/clientmanager/src/main/assets/config.properties @@ -2,7 +2,7 @@ #Crypto asymmetric algorithm name mosip.kernel.crypto.asymmetric-algorithm-name=RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING #Crypto symmetric algorithm name -mosip.kernel.crypto.symmetric-algorithm-name=AES/GCM/PKCS5Padding +mosip.kernel.crypto.symmetric-algorithm-name=AES/GCM/NoPadding #Keygenerator asymmetric algorithm name mosip.kernel.keygenerator.asymmetric-algorithm-name=RSA #Keygenerator symmetric algorithm name diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java index 689003eeb..99f0b8ed4 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java @@ -11,7 +11,14 @@ import androidx.annotation.Nullable; import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; @@ -24,14 +31,19 @@ import java.security.Signature; import java.security.UnrecoverableEntryException; import java.security.cert.CertificateException; +import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Arrays; import java.util.Base64; import java.util.Base64.Decoder; import java.util.Base64.Encoder; +import java.util.Objects; +import javax.crypto.BadPaddingException; import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; import javax.crypto.KeyGenerator; +import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.spec.GCMParameterSpec; import javax.crypto.spec.SecretKeySpec; @@ -92,6 +104,8 @@ public class LocalClientCryptoServiceImpl extends Service implements ClientCrypt private static final String PRIVATE_ALIAS = "PRIVATE_ALIAS"; private static final String SECRET_ALIAS = "SECRET_ALIAS"; + private static String KEYS_DIR = "mosipkeys"; + private static SecureRandom secureRandom = null; @@ -115,8 +129,23 @@ public void initLocalClientCryptoService() { context = getApplicationContext(); initializeClientSecurity(); - genSecretKey(); - genPrivPubKey(); + try { + // keys do not exist + if(!doesKeysExists()) { + Log.d(TAG, "LocalClientCryptoServiceImpl: Keys do not exist. Generating keys "); + genSecretKey(); + genPrivPubKey(); + + + } + else { + Log.d(TAG, "LocalClientCryptoServiceImpl: Keys exist "); + } + + } catch (Exception ex) { + ex.printStackTrace(); + } + Log.d(TAG, "LocalClientCryptoServiceImpl: Initialization call successful"); } @@ -143,6 +172,7 @@ public IBinder onBind(Intent intent) { // stopSelf(); // return START_STICKY; // } + // onDestroy service @Override public void onDestroy() { @@ -198,14 +228,15 @@ private void genSecretKey() { // NOTE:CURRENTLY HARDCODED // [ KEYGEN_SYMMETRIC_ALGO_BLOCK=KeyProperties.BLOCK_MODE_GCM; - KEYGEN_SYMMETRIC_ALGO_PAD=KeyProperties.ENCRYPTION_PADDING_PKCS7; + KEYGEN_SYMMETRIC_ALGO_PAD=KeyProperties.ENCRYPTION_PADDING_NONE; // ] try { KeyGenerator kg = KeyGenerator .getInstance(KEYGEN_SYMMETRIC_ALGORITHM, ANDROID_KEY_STORE); - final KeyGenParameterSpec keyGenParameterSpec = new KeyGenParameterSpec.Builder(SECRET_ALIAS, + final KeyGenParameterSpec keyGenParameterSpec = new KeyGenParameterSpec.Builder( + SECRET_ALIAS, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) .setBlockModes(KEYGEN_SYMMETRIC_ALGO_BLOCK) .setEncryptionPaddings(KEYGEN_SYMMETRIC_ALGO_PAD) @@ -215,7 +246,19 @@ private void genSecretKey() { kg.init(keyGenParameterSpec); SecretKey secretKey = kg.generateKey(); - Log.d(TAG, "LocalClientCryptoServiceImpl: Secret key generation successful"); + byte[] mosipSecretKey = generateRandomBytes(KEYGEN_SYMMETRIC_KEY_LENGTH); + final Cipher cipher_symmetric = Cipher.getInstance(CRYPTO_SYMMETRIC_ALGORITHM); + byte[] iv = cipher_symmetric.getIV(); + cipher_symmetric.init(Cipher.ENCRYPT_MODE, secretKey); + byte[] secret_key_encryption = cipher_symmetric.doFinal(mosipSecretKey); + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream( ); + outputStream.write(iv); + outputStream.write(secret_key_encryption); + + createKeyFile(SECRET_ALIAS, outputStream.toByteArray()); + + Log.d(TAG, "LocalClientCryptoService: Generated secret key successfully " + secret_key_encryption); } catch(Exception ex) { ex.printStackTrace(); @@ -249,7 +292,7 @@ private void genPrivPubKey() { kpg.initialize(keyPairGenParameterSpec); KeyPair kp = kpg.generateKeyPair(); - Log.d(TAG, "LocalClientCryptoServiceImpl: Private key generation successful"); + Log.d(TAG, "LocalClientCryptoService: Generated private key successfully "); } catch(Exception ex) { ex.printStackTrace(); @@ -314,9 +357,10 @@ public CryptoResponseDto encrypt(CryptoRequestDto cryptoRequestDto) { X509EncodedKeySpec keySpec = new X509EncodedKeySpec(public_key); KeyFactory kf = KeyFactory.getInstance(KEYGEN_ASYMMETRIC_ALGORITHM); PublicKey publicKey = kf.generatePublic(keySpec); - + Log.d(TAG, "encrypt: Generated public key obj"); SecretKey secretKey = getSecretKey(); - + Log.d(TAG, "encrypt: Read secret key obj"); + Log.d(TAG, "LocalClientCryptoService: Generated secret key successfully " + secretKey.getEncoded()); // symmetric encryption of data----------------------------------------------------- final Cipher cipher_symmetric = Cipher.getInstance(CRYPTO_SYMMETRIC_ALGORITHM); cipher_symmetric.init(Cipher.ENCRYPT_MODE, secretKey); @@ -324,12 +368,13 @@ public CryptoResponseDto encrypt(CryptoRequestDto cryptoRequestDto) { byte[] aad = generateRandomBytes(AAD_LENGTH); cipher_symmetric.updateAAD(aad); byte[] data_encryption = cipher_symmetric.doFinal(dataToEncrypt); - + Log.d(TAG, "encrypt: Generated message encryption" + data_encryption); // asymmetric encryption of secret key---------------------------------------------------- final Cipher cipher_asymmetric = Cipher.getInstance(CRYPTO_ASYMMETRIC_ALGORITHM); cipher_asymmetric.init(Cipher.ENCRYPT_MODE, publicKey); byte[] key_encryption = cipher_asymmetric.doFinal(secretKey.getEncoded()); + Log.d(TAG, "encrypt: Generated private key encryption"); // storing iv and encryption in encrypted_data ByteArrayOutputStream outputStream = new ByteArrayOutputStream( ); @@ -340,7 +385,7 @@ public CryptoResponseDto encrypt(CryptoRequestDto cryptoRequestDto) { // need to add aad byte[] encrypted_key_iv_data = outputStream.toByteArray(); - + Log.d(TAG, "encrypt: Generated encrypted data"); cryptoResponseDto.setValue(base64encoder.encodeToString(encrypted_key_iv_data)); return cryptoResponseDto; } catch(Exception ex) { @@ -401,15 +446,71 @@ public PublicKeyResponseDto getPublicKey(PublicKeyRequestDto publicKeyRequestDto return null; } + private boolean doesKeysExists() throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableEntryException { + KeyStore ks = KeyStore.getInstance(ANDROID_KEY_STORE); + ks.load(null); + + // check if secret key exists + KeyStore.Entry entry = ks.getEntry(SECRET_ALIAS, null); + if (!(entry instanceof KeyStore.SecretKeyEntry)) { + return false; + } + Log.d(TAG, "doesKeysExists: Secret key exists"); + + // check if private key exists + entry = ks.getEntry(PRIVATE_ALIAS, null); + if (!(entry instanceof KeyStore.PrivateKeyEntry)) { + return false; + } + Log.d(TAG, "doesKeysExists: Private key exists"); + + // check if mosip secret key exists + File keysDir = new File(getKeysDirPath()); + if(!keysDir.exists()) { + return false; + } + + Log.d(TAG, "doesKeysExists: Mosip key exists"); + return true; + } + + private String getKeysDirPath() { +// return KEYS_DIR + File.separator + SECRET_ALIAS; + return SECRET_ALIAS; + } + + // create a key file to store the encrypted secret key + private void createKeyFile(String fileName, byte[] key) throws IOException { + + try(FileOutputStream fos = openFileOutput(getKeysDirPath(), Context.MODE_PRIVATE)) { + fos.write(key); + } + + + } + + // get secret key from keystore - private SecretKey getSecretKey() throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableEntryException { + private SecretKey getSecretKey() throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableEntryException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { KeyStore ks = KeyStore.getInstance(ANDROID_KEY_STORE); ks.load(null); KeyStore.Entry entry = ks.getEntry(SECRET_ALIAS, null); if (!(entry instanceof KeyStore.SecretKeyEntry)) { return null; } - return ((KeyStore.SecretKeyEntry) entry).getSecretKey(); + + SecretKey secretKey = ((KeyStore.SecretKeyEntry) entry).getSecretKey(); + + byte[] secret_key_encryption = new byte[256]; + FileInputStream fis = openFileInput(getKeysDirPath()); + fis.read(secret_key_encryption); + fis.close(); + + final Cipher cipher_symmetric = Cipher.getInstance(CRYPTO_SYMMETRIC_ALGORITHM); + cipher_symmetric.init(Cipher.DECRYPT_MODE, secretKey); + byte[] mosipSecretKey = cipher_symmetric.doFinal(secret_key_encryption); + + return new SecretKeySpec(mosipSecretKey, 0, mosipSecretKey.length, KEYGEN_SYMMETRIC_ALGORITHM); } // get private key from keystore @@ -420,6 +521,7 @@ private PrivateKey getPrivateKey() throws KeyStoreException, CertificateExceptio if (!(entry instanceof KeyStore.PrivateKeyEntry)) { return null; } + return ((KeyStore.PrivateKeyEntry) entry).getPrivateKey(); } From e397f7ec5922a9c2fd9e6131a141ad054925125a Mon Sep 17 00:00:00 2001 From: EricJohnEastwood Date: Mon, 13 Sep 2021 15:33:13 +0530 Subject: [PATCH 15/27] Add secret key generation --- .../mosip/registration/app/MainActivity.java | 45 ++++++++++++++++++- .../crypto/LocalClientCryptoServiceImpl.java | 31 ++++++++----- 2 files changed, 64 insertions(+), 12 deletions(-) diff --git a/client/app/src/main/java/io/mosip/registration/app/MainActivity.java b/client/app/src/main/java/io/mosip/registration/app/MainActivity.java index 7edea93aa..fc23b390c 100644 --- a/client/app/src/main/java/io/mosip/registration/app/MainActivity.java +++ b/client/app/src/main/java/io/mosip/registration/app/MainActivity.java @@ -27,6 +27,7 @@ public class MainActivity extends AppCompatActivity { private boolean mStopLoop; TextView textView; + private String encryption; @Override @@ -81,12 +82,54 @@ public void run() { e.printStackTrace(); } textView.setText(cryptoResponseDto.getValue()); + encryption = cryptoResponseDto.getValue(); } }).start(); } public void click_decrypt(View view) { - textView.setText("Clicked Decrypt"); + + new Thread(new Runnable() { + @Override + public void run() { + try { + PublicKeyRequestDto publicKeyRequestDto=new PublicKeyRequestDto(); + PublicKeyResponseDto publicKeyResponseDto=localClientCryptoService.getPublicKey(publicKeyRequestDto); +// PublicKeyResponseDto publicKeyResponseDto; + textView.setText("Got public key..creating cryptoRequest for decrypt"); + try{ + Thread.sleep(2000); + }catch(InterruptedException e){ + System.out.println(e); + } + + CryptoRequestDto cryptoRequestDto = new CryptoRequestDto(encryption, publicKeyResponseDto.getPublicKey()); + textView.setText("Decrypting......"); + try{ + Thread.sleep(2000); + }catch(InterruptedException e){ + System.out.println(e); + } + + CryptoResponseDto cryptoResponseDto=localClientCryptoService.decrypt(cryptoRequestDto); + System.out.println(cryptoResponseDto.getValue()); + textView.setText("Decrypted message is : "+cryptoResponseDto.getValue() ); + + try{ + Thread.sleep(2000); + }catch(InterruptedException e){ + System.out.println(e); + } + + } catch(Exception ex) { + ex.printStackTrace(); + } + + + textView.setText("Clicked Decrypt"); + } + }).start(); + } diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java index 99f0b8ed4..ddce845e3 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java @@ -245,20 +245,22 @@ private void genSecretKey() { kg.init(keyGenParameterSpec); SecretKey secretKey = kg.generateKey(); + Log.d(TAG, "LocalClientCryptoService: Generated secret key successfully"); - byte[] mosipSecretKey = generateRandomBytes(KEYGEN_SYMMETRIC_KEY_LENGTH); + byte[] mosipSecretKey = generateRandomBytes(KEYGEN_SYMMETRIC_KEY_LENGTH/8); final Cipher cipher_symmetric = Cipher.getInstance(CRYPTO_SYMMETRIC_ALGORITHM); - byte[] iv = cipher_symmetric.getIV(); cipher_symmetric.init(Cipher.ENCRYPT_MODE, secretKey); + byte[] iv = cipher_symmetric.getIV(); byte[] secret_key_encryption = cipher_symmetric.doFinal(mosipSecretKey); ByteArrayOutputStream outputStream = new ByteArrayOutputStream( ); outputStream.write(iv); outputStream.write(secret_key_encryption); + byte[] encryption_iv_secretKey = outputStream.toByteArray(); - createKeyFile(SECRET_ALIAS, outputStream.toByteArray()); + createKeyFile(SECRET_ALIAS, encryption_iv_secretKey); - Log.d(TAG, "LocalClientCryptoService: Generated secret key successfully " + secret_key_encryption); + Log.d(TAG, "LocalClientCryptoService: Generated mosip key successfully " + mosipSecretKey); } catch(Exception ex) { ex.printStackTrace(); @@ -357,10 +359,10 @@ public CryptoResponseDto encrypt(CryptoRequestDto cryptoRequestDto) { X509EncodedKeySpec keySpec = new X509EncodedKeySpec(public_key); KeyFactory kf = KeyFactory.getInstance(KEYGEN_ASYMMETRIC_ALGORITHM); PublicKey publicKey = kf.generatePublic(keySpec); - Log.d(TAG, "encrypt: Generated public key obj"); + Log.d(TAG, "encrypt: Read public key obj"); SecretKey secretKey = getSecretKey(); Log.d(TAG, "encrypt: Read secret key obj"); - Log.d(TAG, "LocalClientCryptoService: Generated secret key successfully " + secretKey.getEncoded()); + Log.d(TAG, "LocalClientCryptoService: Read secret key successfully " + secretKey.getEncoded()); // symmetric encryption of data----------------------------------------------------- final Cipher cipher_symmetric = Cipher.getInstance(CRYPTO_SYMMETRIC_ALGORITHM); cipher_symmetric.init(Cipher.ENCRYPT_MODE, secretKey); @@ -501,16 +503,23 @@ private SecretKey getSecretKey() throws KeyStoreException, CertificateException, SecretKey secretKey = ((KeyStore.SecretKeyEntry) entry).getSecretKey(); - byte[] secret_key_encryption = new byte[256]; + FileInputStream fis = openFileInput(getKeysDirPath()); - fis.read(secret_key_encryption); + int size = (int) fis.getChannel().size(); + byte[] encryption_iv_secretKey = new byte[size]; + fis.read(encryption_iv_secretKey); fis.close(); + byte[] iv = Arrays.copyOfRange(encryption_iv_secretKey, 0, IV_LENGTH); + byte[] encryptedSecretKey = Arrays.copyOfRange(encryption_iv_secretKey, IV_LENGTH, size); + final Cipher cipher_symmetric = Cipher.getInstance(CRYPTO_SYMMETRIC_ALGORITHM); - cipher_symmetric.init(Cipher.DECRYPT_MODE, secretKey); - byte[] mosipSecretKey = cipher_symmetric.doFinal(secret_key_encryption); + final GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(CRYPTO_GCM_TAG_LENGTH, iv); + cipher_symmetric.init(Cipher.DECRYPT_MODE, secretKey, gcmParameterSpec); + byte[] mosipSecretKey = cipher_symmetric.doFinal(encryptedSecretKey); - return new SecretKeySpec(mosipSecretKey, 0, mosipSecretKey.length, KEYGEN_SYMMETRIC_ALGORITHM); + SecretKey mosip_secret_key = new SecretKeySpec(mosipSecretKey, 0, mosipSecretKey.length, KEYGEN_SYMMETRIC_ALGORITHM); + return mosip_secret_key; } // get private key from keystore From 5b27df796a3e0ffc8263086311e249603c7a6ad5 Mon Sep 17 00:00:00 2001 From: EricJohnEastwood Date: Wed, 15 Sep 2021 11:45:06 +0530 Subject: [PATCH 16/27] Add mosipSecretKey store --- .../mosip/registration/app/MainActivity.java | 2 - .../crypto/LocalClientCryptoServiceImpl.java | 207 ++++++++++-------- 2 files changed, 113 insertions(+), 96 deletions(-) diff --git a/client/app/src/main/java/io/mosip/registration/app/MainActivity.java b/client/app/src/main/java/io/mosip/registration/app/MainActivity.java index fc23b390c..d8dedecf4 100644 --- a/client/app/src/main/java/io/mosip/registration/app/MainActivity.java +++ b/client/app/src/main/java/io/mosip/registration/app/MainActivity.java @@ -67,8 +67,6 @@ public void run() { CryptoResponseDto cryptoResponseDto = localClientCryptoService.encrypt(cryptoRequestDto); -// SignRequestDto signRequestDto = new SignRequestDto("dummy"); - try{ Thread.sleep(2000); }catch(InterruptedException e){ diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java index ddce845e3..9ca223de3 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java @@ -15,6 +15,8 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.io.OutputStreamWriter; +import java.nio.file.AccessDeniedException; import java.nio.file.Files; import java.nio.file.Paths; import java.security.InvalidAlgorithmParameterException; @@ -31,6 +33,7 @@ import java.security.Signature; import java.security.UnrecoverableEntryException; import java.security.cert.CertificateException; +import java.security.spec.MGF1ParameterSpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Arrays; @@ -46,6 +49,8 @@ import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.spec.GCMParameterSpec; +import javax.crypto.spec.OAEPParameterSpec; +import javax.crypto.spec.PSource; import javax.crypto.spec.SecretKeySpec; import javax.inject.Inject; import javax.inject.Singleton; @@ -132,14 +137,14 @@ public void initLocalClientCryptoService() { try { // keys do not exist if(!doesKeysExists()) { - Log.d(TAG, "LocalClientCryptoServiceImpl: Keys do not exist. Generating keys "); + Log.e(TAG, "LocalClientCryptoServiceImpl: Keys do not exist. Generating keys "); genSecretKey(); genPrivPubKey(); } else { - Log.d(TAG, "LocalClientCryptoServiceImpl: Keys exist "); + Log.e(TAG, "LocalClientCryptoServiceImpl: Keys exist "); } } catch (Exception ex) { @@ -147,7 +152,7 @@ public void initLocalClientCryptoService() { } - Log.d(TAG, "LocalClientCryptoServiceImpl: Initialization call successful"); + Log.e(TAG, "LocalClientCryptoServiceImpl: Initialization call successful"); } // ON BIND BINDER FOR MAIN CLASS HERE @@ -221,46 +226,48 @@ private void initializeClientSecurity() { } private void genSecretKey() { - // hardcoding some initializations for now - // for symmetric encryption---------------------------------------------------------- - - // first set the encryption algorithm variables like blocks,padding,key length etc.....should be originally from the config file - // NOTE:CURRENTLY HARDCODED - // [ - KEYGEN_SYMMETRIC_ALGO_BLOCK=KeyProperties.BLOCK_MODE_GCM; - KEYGEN_SYMMETRIC_ALGO_PAD=KeyProperties.ENCRYPTION_PADDING_NONE; - // ] + KEYGEN_ASYMMETRIC_ALGO_BLOCK=KeyProperties.BLOCK_MODE_ECB; + KEYGEN_ASYMMETRIC_ALGO_PAD=KeyProperties.ENCRYPTION_PADDING_RSA_OAEP; try { - KeyGenerator kg = KeyGenerator - .getInstance(KEYGEN_SYMMETRIC_ALGORITHM, ANDROID_KEY_STORE); + KeyPairGenerator kpg = KeyPairGenerator.getInstance( + KEYGEN_ASYMMETRIC_ALGORITHM, ANDROID_KEY_STORE); - final KeyGenParameterSpec keyGenParameterSpec = new KeyGenParameterSpec.Builder( + final KeyGenParameterSpec keyPairGenParameterSpec = new KeyGenParameterSpec.Builder( SECRET_ALIAS, - KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) - .setBlockModes(KEYGEN_SYMMETRIC_ALGO_BLOCK) - .setEncryptionPaddings(KEYGEN_SYMMETRIC_ALGO_PAD) - .setKeySize(KEYGEN_SYMMETRIC_KEY_LENGTH) + KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) + .setBlockModes(KEYGEN_ASYMMETRIC_ALGO_BLOCK) + .setKeySize(KEYGEN_ASYMMETRIC_KEY_LENGTH) + .setEncryptionPaddings(KEYGEN_ASYMMETRIC_ALGO_PAD) +// .setUserAuthenticationRequired(true) + .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512) .build(); - kg.init(keyGenParameterSpec); - SecretKey secretKey = kg.generateKey(); - Log.d(TAG, "LocalClientCryptoService: Generated secret key successfully"); + kpg.initialize(keyPairGenParameterSpec); + KeyPair kp = kpg.generateKeyPair(); - byte[] mosipSecretKey = generateRandomBytes(KEYGEN_SYMMETRIC_KEY_LENGTH/8); - final Cipher cipher_symmetric = Cipher.getInstance(CRYPTO_SYMMETRIC_ALGORITHM); - cipher_symmetric.init(Cipher.ENCRYPT_MODE, secretKey); - byte[] iv = cipher_symmetric.getIV(); - byte[] secret_key_encryption = cipher_symmetric.doFinal(mosipSecretKey); + PublicKey publicKey = kp.getPublic(); - ByteArrayOutputStream outputStream = new ByteArrayOutputStream( ); - outputStream.write(iv); - outputStream.write(secret_key_encryption); - byte[] encryption_iv_secretKey = outputStream.toByteArray(); + Log.e(TAG, "genSecretKey: Generated private key successfully " + kp.getPublic()); + + KeyGenerator keyGen = KeyGenerator.getInstance(KEYGEN_SYMMETRIC_ALGORITHM); + keyGen.init(KEYGEN_SYMMETRIC_KEY_LENGTH); + SecretKey mosipSecretKey = keyGen.generateKey(); - createKeyFile(SECRET_ALIAS, encryption_iv_secretKey); + Log.e(TAG, "genSecretKey: Generated mosip key successfully " + mosipSecretKey.getEncoded()); - Log.d(TAG, "LocalClientCryptoService: Generated mosip key successfully " + mosipSecretKey); + final Cipher cipher_asymmetric = Cipher.getInstance(CRYPTO_ASYMMETRIC_ALGORITHM); + OAEPParameterSpec spec = new OAEPParameterSpec( + "SHA-256", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT); + cipher_asymmetric.init(Cipher.ENCRYPT_MODE, publicKey, spec); + + byte[] secretKeyEncryption = cipher_asymmetric.doFinal(mosipSecretKey.getEncoded()); + Log.e(TAG, "genSecretKey: Generated secret key encryption"); + + Log.e(TAG, "getSecretKey: Key length " + (secretKeyEncryption.length)); + createKeyFile(getKeysDirPath(), secretKeyEncryption); + + Log.e(TAG, "genSecretKey: Generated secret key successfully "); } catch(Exception ex) { ex.printStackTrace(); @@ -268,13 +275,9 @@ private void genSecretKey() { } private void genPrivPubKey() { - // for asymmetric encryption storing keypair--------------------------- - //set the asymmetric encryption algorithm variables like blocks,padding,key length etc.....should be originally from the config file - // NOTE:CURRENTLY HARDCODED - // [ + KEYGEN_ASYMMETRIC_ALGO_BLOCK=KeyProperties.BLOCK_MODE_ECB; KEYGEN_ASYMMETRIC_ALGO_PAD=KeyProperties.ENCRYPTION_PADDING_RSA_OAEP; - // ] try { // lot of errors in asymmetric part @@ -288,13 +291,13 @@ private void genPrivPubKey() { .setBlockModes(KEYGEN_ASYMMETRIC_ALGO_BLOCK) .setKeySize(KEYGEN_ASYMMETRIC_KEY_LENGTH) .setEncryptionPaddings(KEYGEN_ASYMMETRIC_ALGO_PAD) - .setDigests(KeyProperties.DIGEST_SHA256) +// .setUserAuthenticationRequired(true) + .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512) .build(); kpg.initialize(keyPairGenParameterSpec); KeyPair kp = kpg.generateKeyPair(); - - Log.d(TAG, "LocalClientCryptoService: Generated private key successfully "); + Log.e(TAG, "genPrivateKey: Generated private key successfully " + base64encoder.encodeToString(kp.getPublic().getEncoded())); } catch(Exception ex) { ex.printStackTrace(); @@ -359,24 +362,26 @@ public CryptoResponseDto encrypt(CryptoRequestDto cryptoRequestDto) { X509EncodedKeySpec keySpec = new X509EncodedKeySpec(public_key); KeyFactory kf = KeyFactory.getInstance(KEYGEN_ASYMMETRIC_ALGORITHM); PublicKey publicKey = kf.generatePublic(keySpec); - Log.d(TAG, "encrypt: Read public key obj"); - SecretKey secretKey = getSecretKey(); - Log.d(TAG, "encrypt: Read secret key obj"); - Log.d(TAG, "LocalClientCryptoService: Read secret key successfully " + secretKey.getEncoded()); + Log.e(TAG, "encrypt: Read public key obj"); + SecretKey mosipSecretKey = getSecretKey(); + Log.e(TAG, "encrypt: Read mosip key successfully " + mosipSecretKey.getEncoded()); // symmetric encryption of data----------------------------------------------------- final Cipher cipher_symmetric = Cipher.getInstance(CRYPTO_SYMMETRIC_ALGORITHM); - cipher_symmetric.init(Cipher.ENCRYPT_MODE, secretKey); + + cipher_symmetric.init(Cipher.ENCRYPT_MODE, mosipSecretKey); byte[] iv = cipher_symmetric.getIV(); byte[] aad = generateRandomBytes(AAD_LENGTH); cipher_symmetric.updateAAD(aad); byte[] data_encryption = cipher_symmetric.doFinal(dataToEncrypt); - Log.d(TAG, "encrypt: Generated message encryption" + data_encryption); + Log.e(TAG, "encrypt: Generated message encryption" + data_encryption); // asymmetric encryption of secret key---------------------------------------------------- final Cipher cipher_asymmetric = Cipher.getInstance(CRYPTO_ASYMMETRIC_ALGORITHM); - cipher_asymmetric.init(Cipher.ENCRYPT_MODE, publicKey); - byte[] key_encryption = cipher_asymmetric.doFinal(secretKey.getEncoded()); - Log.d(TAG, "encrypt: Generated private key encryption"); + OAEPParameterSpec spec = new OAEPParameterSpec( + "SHA-256", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT); + cipher_asymmetric.init(Cipher.ENCRYPT_MODE, publicKey,spec); + byte[] key_encryption = cipher_asymmetric.doFinal(mosipSecretKey.getEncoded()); + Log.e(TAG, "encrypt: Generated secret key encryption"); // storing iv and encryption in encrypted_data ByteArrayOutputStream outputStream = new ByteArrayOutputStream( ); @@ -387,7 +392,7 @@ public CryptoResponseDto encrypt(CryptoRequestDto cryptoRequestDto) { // need to add aad byte[] encrypted_key_iv_data = outputStream.toByteArray(); - Log.d(TAG, "encrypt: Generated encrypted data"); + Log.e(TAG, "encrypt: Generated encrypted data"); cryptoResponseDto.setValue(base64encoder.encodeToString(encrypted_key_iv_data)); return cryptoResponseDto; } catch(Exception ex) { @@ -440,6 +445,7 @@ public PublicKeyResponseDto getPublicKey(PublicKeyRequestDto publicKeyRequestDto try { PublicKey publicKey = getPublicKey(); String public_key = base64encoder.encodeToString(publicKey.getEncoded()); + Log.e(TAG, "getPublicKey: Public key accessed " + public_key); publicKeyResponseDto.setPublicKey(public_key); return publicKeyResponseDto; } catch(Exception ex) { @@ -457,22 +463,22 @@ private boolean doesKeysExists() throws KeyStoreException, CertificateException, if (!(entry instanceof KeyStore.SecretKeyEntry)) { return false; } - Log.d(TAG, "doesKeysExists: Secret key exists"); + Log.e(TAG, "doesKeysExists: Secret key exists"); // check if private key exists entry = ks.getEntry(PRIVATE_ALIAS, null); if (!(entry instanceof KeyStore.PrivateKeyEntry)) { return false; } - Log.d(TAG, "doesKeysExists: Private key exists"); + Log.e(TAG, "doesKeysExists: Private key exists"); - // check if mosip secret key exists - File keysDir = new File(getKeysDirPath()); - if(!keysDir.exists()) { + File file = new File(context.getFilesDir(),getKeysDirPath()); + if(!file.exists()) { + file.createNewFile(); + Log.e(TAG, "doesKeysExists: File created..."); return false; } - - Log.d(TAG, "doesKeysExists: Mosip key exists"); + Log.e(TAG, "doesKeysExists: Mosip key exists"); return true; } @@ -482,13 +488,30 @@ private String getKeysDirPath() { } // create a key file to store the encrypted secret key - private void createKeyFile(String fileName, byte[] key) throws IOException { - - try(FileOutputStream fos = openFileOutput(getKeysDirPath(), Context.MODE_PRIVATE)) { - fos.write(key); - } + private void createKeyFile(String keyDir, byte[] key) throws IOException { + String keyEncoded = Base64.getEncoder().encodeToString(key); + try { + File file = new File(context.getFilesDir(), getKeysDirPath()); + if(!file.exists()) { + try { + file.createNewFile(); + Log.e(TAG, "createKeyFile: File"); + } catch (AccessDeniedException ex) { + Log.e(TAG, "createKeyFile: Access Denied", ex); + } + } + FileOutputStream stream = new FileOutputStream(file); + try { + stream.write(keyEncoded.getBytes()); + } finally { + stream.close(); + } + Log.e(TAG, "createKeyFile: key " + keyEncoded); + } catch (Exception ex) { + ex.printStackTrace(); + } } @@ -496,54 +519,50 @@ private void createKeyFile(String fileName, byte[] key) throws IOException { private SecretKey getSecretKey() throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableEntryException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { KeyStore ks = KeyStore.getInstance(ANDROID_KEY_STORE); ks.load(null); - KeyStore.Entry entry = ks.getEntry(SECRET_ALIAS, null); - if (!(entry instanceof KeyStore.SecretKeyEntry)) { - return null; + PrivateKey privateKey = (PrivateKey) ks.getKey(SECRET_ALIAS, null); + + String keyEncoded = ""; + File file = new File(context.getFilesDir(), getKeysDirPath()); + if(file.exists()) { + int length = (int) file.length(); + byte[] bytes = new byte[length]; + FileInputStream in = new FileInputStream(file); + try { + in.read(bytes); + } finally { + in.close(); + } + keyEncoded += new String(bytes); + Log.e(TAG, "createKeyFile: key " + keyEncoded); + } + else { + Log.e(TAG, "getSecretKey: File not exists"); } - SecretKey secretKey = ((KeyStore.SecretKeyEntry) entry).getSecretKey(); - - - FileInputStream fis = openFileInput(getKeysDirPath()); - int size = (int) fis.getChannel().size(); - byte[] encryption_iv_secretKey = new byte[size]; - fis.read(encryption_iv_secretKey); - fis.close(); + byte[] secretKeyEncryption = base64decoder.decode(keyEncoded); + Log.e(TAG, "getSecretKey: Key length " + (secretKeyEncryption.length)); - byte[] iv = Arrays.copyOfRange(encryption_iv_secretKey, 0, IV_LENGTH); - byte[] encryptedSecretKey = Arrays.copyOfRange(encryption_iv_secretKey, IV_LENGTH, size); - final Cipher cipher_symmetric = Cipher.getInstance(CRYPTO_SYMMETRIC_ALGORITHM); - final GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(CRYPTO_GCM_TAG_LENGTH, iv); - cipher_symmetric.init(Cipher.DECRYPT_MODE, secretKey, gcmParameterSpec); - byte[] mosipSecretKey = cipher_symmetric.doFinal(encryptedSecretKey); + final Cipher cipher_asymmetric = Cipher.getInstance(CRYPTO_ASYMMETRIC_ALGORITHM); + cipher_asymmetric.init(Cipher.DECRYPT_MODE, privateKey); - SecretKey mosip_secret_key = new SecretKeySpec(mosipSecretKey, 0, mosipSecretKey.length, KEYGEN_SYMMETRIC_ALGORITHM); - return mosip_secret_key; + byte[] secretKeyBytes = cipher_asymmetric.doFinal(secretKeyEncryption); + Log.e(TAG, "getSecretKey: secretKeyBytes " + secretKeyBytes); + return new SecretKeySpec(secretKeyBytes, KEYGEN_SYMMETRIC_ALGORITHM); } // get private key from keystore private PrivateKey getPrivateKey() throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableEntryException { KeyStore ks = KeyStore.getInstance(ANDROID_KEY_STORE); ks.load(null); - KeyStore.Entry entry = ks.getEntry(PRIVATE_ALIAS, null); - if (!(entry instanceof KeyStore.PrivateKeyEntry)) { - return null; - } - - return ((KeyStore.PrivateKeyEntry) entry).getPrivateKey(); + return (PrivateKey) ks.getKey(PRIVATE_ALIAS, null); } // get public key from keystore private PublicKey getPublicKey() throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableEntryException { KeyStore ks = KeyStore.getInstance(ANDROID_KEY_STORE); ks.load(null); - KeyStore.Entry entry = ks.getEntry(PRIVATE_ALIAS, null); - if (!(entry instanceof KeyStore.PrivateKeyEntry)) { - return null; - } - - return ((KeyStore.PrivateKeyEntry) entry).getCertificate().getPublicKey(); + return (PublicKey) ks.getCertificate(PRIVATE_ALIAS).getPublicKey(); } // random byte generation for AAD From 7caa06d486f0d6ef6a6eeea4a35df04952a93a61 Mon Sep 17 00:00:00 2001 From: EricJohnEastwood Date: Wed, 15 Sep 2021 15:48:34 +0530 Subject: [PATCH 17/27] Fix encoding ambiguity --- .../java/io/mosip/registration/app/MainActivity.java | 2 +- .../service/crypto/LocalClientCryptoServiceImpl.java | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/client/app/src/main/java/io/mosip/registration/app/MainActivity.java b/client/app/src/main/java/io/mosip/registration/app/MainActivity.java index d8dedecf4..f78ddaa68 100644 --- a/client/app/src/main/java/io/mosip/registration/app/MainActivity.java +++ b/client/app/src/main/java/io/mosip/registration/app/MainActivity.java @@ -63,7 +63,7 @@ public void run() { textView.setText("Got public key..creating cryptoRequest"); CryptoRequestDto cryptoRequestDto = new CryptoRequestDto( - "message", publicKeyResponseDto.getPublicKey()); + "This is a new message.Hoergt this workds", publicKeyResponseDto.getPublicKey()); CryptoResponseDto cryptoResponseDto = localClientCryptoService.encrypt(cryptoRequestDto); diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java index 9ca223de3..b936f4e90 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java @@ -357,7 +357,8 @@ public CryptoResponseDto encrypt(CryptoRequestDto cryptoRequestDto) { CryptoResponseDto cryptoResponseDto = new CryptoResponseDto(); byte[] public_key = base64decoder.decode(cryptoRequestDto.getPublicKey()); - byte[] dataToEncrypt = base64decoder.decode(cryptoRequestDto.getValue()); + byte[] dataToEncrypt = base64decoder.decode(base64encoder.encodeToString(cryptoRequestDto.getValue().getBytes())); + try { X509EncodedKeySpec keySpec = new X509EncodedKeySpec(public_key); KeyFactory kf = KeyFactory.getInstance(KEYGEN_ASYMMETRIC_ALGORITHM); @@ -428,9 +429,9 @@ public CryptoResponseDto decrypt(CryptoRequestDto cryptoRequestDto) { final GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(CRYPTO_GCM_TAG_LENGTH, iv); cipher_symmetric.init(Cipher.DECRYPT_MODE, secretKey, gcmParameterSpec); cipher_symmetric.updateAAD(aad); - String decrypted_data = base64encoder.encodeToString(cipher_symmetric.doFinal(encrypted_data)); - - cryptoResponseDto.setValue(decrypted_data); + byte[] decodedBytes = cipher_symmetric.doFinal(encrypted_data); + String decodedString = new String(decodedBytes); + cryptoResponseDto.setValue(decodedString); return cryptoResponseDto; } catch(Exception ex) { ex.printStackTrace(); From b041dbab66482a1afdc298dfe3b8d983317a5080 Mon Sep 17 00:00:00 2001 From: EricJohnEastwood Date: Wed, 15 Sep 2021 22:54:39 +0530 Subject: [PATCH 18/27] Fix sign padding --- .../mosip/registration/app/MainActivity.java | 107 +++++++++++++++++- .../crypto/LocalClientCryptoServiceImpl.java | 20 ++-- 2 files changed, 117 insertions(+), 10 deletions(-) diff --git a/client/app/src/main/java/io/mosip/registration/app/MainActivity.java b/client/app/src/main/java/io/mosip/registration/app/MainActivity.java index f78ddaa68..5bdd05f4d 100644 --- a/client/app/src/main/java/io/mosip/registration/app/MainActivity.java +++ b/client/app/src/main/java/io/mosip/registration/app/MainActivity.java @@ -28,6 +28,7 @@ public class MainActivity extends AppCompatActivity { TextView textView; private String encryption; + private String signed_string; @Override @@ -38,9 +39,15 @@ protected void onCreate(Bundle savedInstanceState) { serviceIntent= new Intent(getApplicationContext(), LocalClientCryptoServiceImpl.class); bindService(); } + public void click_encrypt(View view) { + test_sign(view); + }; + public void click_decrypt(View view) { + test_verify(view); + }; - public void click_encrypt(View view) { + public void test_encrypt(View view) { textView.setText("Clicked Encrypt"); try{ Thread.sleep(2000); @@ -85,7 +92,7 @@ public void run() { }).start(); } - public void click_decrypt(View view) { + public void test_decrypt(View view) { new Thread(new Runnable() { @Override @@ -130,6 +137,102 @@ public void run() { } + // click_sign + public void test_sign(View view){ + new Thread(new Runnable() { + @Override + public void run() { + try { + textView.setText("Clicked Sign Data.Data is: message to sign"); + try{ + Thread.sleep(2000); + }catch(InterruptedException e){ + System.out.println(e); + } + + textView.setText("Creating Sign Request "); + try{ + Thread.sleep(2000); + }catch(InterruptedException e){ + System.out.println(e); + } + + SignRequestDto signRequestDto=new SignRequestDto("message to sign"); + SignResponseDto signResponseDto=localClientCryptoService.sign(signRequestDto); + signed_string=signResponseDto.getData(); + + textView.setText("Signature Generated for string"); + try{ + Thread.sleep(2000); + }catch(InterruptedException e){ + System.out.println(e); + } + + textView.setText("Signature is: "+ signed_string); + try{ + Thread.sleep(2000); + }catch(InterruptedException e){ + System.out.println(e); + } + + + } + catch (Exception ex){ + ex.printStackTrace(); + } + + } + }).start(); + + } + + + // verifying + // click_verify + public void test_verify(View view){ + + new Thread(new Runnable() { + @Override + public void run() { + try{ + PublicKeyRequestDto publicKeyRequestDto=new PublicKeyRequestDto(); + PublicKeyResponseDto publicKeyResponseDto=localClientCryptoService.getPublicKey(publicKeyRequestDto); +// PublicKeyResponseDto publicKeyResponseDto; + textView.setText("Got public key..verifying signed data"); + try{ + Thread.sleep(2000); + }catch(InterruptedException e){ + System.out.println(e); + } + + + SignVerifyRequestDto signVerifyRequestDto=new SignVerifyRequestDto("message to sign",signed_string,publicKeyResponseDto.getPublicKey()); + SignVerifyResponseDto signVerifyResponseDto=localClientCryptoService.verifySign(signVerifyRequestDto); + + textView.setText("Verified Data"); + try{ + Thread.sleep(2000); + }catch(InterruptedException e){ + System.out.println(e); + } + + if(signVerifyResponseDto.isVerified()){ + textView.setText("Data is correctly signed and matching"); + } + else{ + textView.setText("Incorrect Signature"); + } + + }catch(Exception ex){ + ex.printStackTrace(); + } + + } + + }).start(); + + } + private void bindService(){ if(serviceConnection==null){ diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java index b936f4e90..a61ba7ad0 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java @@ -83,6 +83,7 @@ public class LocalClientCryptoServiceImpl extends Service implements ClientCrypt private static String KEYGEN_ASYMMETRIC_ALGORITHM; private static String KEYGEN_ASYMMETRIC_ALGO_BLOCK; private static String KEYGEN_ASYMMETRIC_ALGO_PAD; + private static String KEYGEN_ASYMMETRIC_ALGO_SIGN_PAD; private static int KEYGEN_ASYMMETRIC_KEY_LENGTH; // symmetric encryption details together----------------------------- @@ -108,6 +109,7 @@ public class LocalClientCryptoServiceImpl extends Service implements ClientCrypt private static final String ANDROID_KEY_STORE = "AndroidKeyStore"; private static final String PRIVATE_ALIAS = "PRIVATE_ALIAS"; private static final String SECRET_ALIAS = "SECRET_ALIAS"; + private static final String SIGN_ALIAS = "SIGN_ALIAS"; private static String KEYS_DIR = "mosipkeys"; @@ -221,6 +223,7 @@ private void initializeClientSecurity() { CRYPTO_SIGN_ALGORITHM = ConfigService.getProperty("mosip.kernel.crypto.sign-algorithm-name",context); CERTIFICATE_SIGN_ALGORITHM = ConfigService.getProperty("mosip.kernel.certificate.sign.algorithm",context); + base64encoder = Base64.getEncoder(); base64decoder = Base64.getDecoder(); } @@ -276,8 +279,9 @@ private void genSecretKey() { private void genPrivPubKey() { - KEYGEN_ASYMMETRIC_ALGO_BLOCK=KeyProperties.BLOCK_MODE_ECB; - KEYGEN_ASYMMETRIC_ALGO_PAD=KeyProperties.ENCRYPTION_PADDING_RSA_OAEP; + KEYGEN_ASYMMETRIC_ALGO_BLOCK = KeyProperties.BLOCK_MODE_ECB; + KEYGEN_ASYMMETRIC_ALGO_PAD = KeyProperties.ENCRYPTION_PADDING_RSA_OAEP; + KEYGEN_ASYMMETRIC_ALGO_SIGN_PAD = KeyProperties.SIGNATURE_PADDING_RSA_PKCS1; try { // lot of errors in asymmetric part @@ -291,7 +295,7 @@ private void genPrivPubKey() { .setBlockModes(KEYGEN_ASYMMETRIC_ALGO_BLOCK) .setKeySize(KEYGEN_ASYMMETRIC_KEY_LENGTH) .setEncryptionPaddings(KEYGEN_ASYMMETRIC_ALGO_PAD) -// .setUserAuthenticationRequired(true) + .setSignaturePaddings(KEYGEN_ASYMMETRIC_ALGO_SIGN_PAD) .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512) .build(); @@ -308,11 +312,10 @@ private void genPrivPubKey() { public SignResponseDto sign(SignRequestDto signRequestDto) { SignResponseDto signResponseDto = new SignResponseDto(); - byte[] dataToSign = base64decoder.decode(signRequestDto.getData()); + byte[] dataToSign = base64decoder.decode(base64encoder.encodeToString(signRequestDto.getData().getBytes())); try { PrivateKey privateKey = getPrivateKey(); - - Signature sign = Signature.getInstance(CRYPTO_SIGN_ALGORITHM); + Signature sign = Signature.getInstance(CERTIFICATE_SIGN_ALGORITHM); sign.initSign(privateKey); sign.update(dataToSign); byte[] signedData = sign.sign(); @@ -332,13 +335,14 @@ public SignVerifyResponseDto verifySign(SignVerifyRequestDto signVerifyRequestDt byte[] public_key = base64decoder.decode(signVerifyRequestDto.getPublicKey()); byte[] signature = base64decoder.decode(signVerifyRequestDto.getSignature()); - byte[] actualData = base64decoder.decode(signVerifyRequestDto.getData()); + byte[] actualData = base64decoder.decode(base64encoder.encodeToString(signVerifyRequestDto.getData().getBytes())); + try { X509EncodedKeySpec keySpec = new X509EncodedKeySpec(public_key); KeyFactory kf = KeyFactory.getInstance(KEYGEN_ASYMMETRIC_ALGORITHM); PublicKey publicKey = kf.generatePublic(keySpec); - Signature sign = Signature.getInstance(CRYPTO_SIGN_ALGORITHM); + Signature sign = Signature.getInstance(CERTIFICATE_SIGN_ALGORITHM); sign.initVerify(publicKey); sign.update(actualData); boolean result = sign.verify(signature); From ed9724f99f936e0fba63a48f90498b5638f38dc5 Mon Sep 17 00:00:00 2001 From: EricJohnEastwood Date: Tue, 28 Sep 2021 12:38:01 +0530 Subject: [PATCH 19/27] Cleanup LocalClientCryptoServiceImpl --- .../mosip/registration/app/MainActivity.java | 226 +++++--------- .../src/main/assets/config.properties | 8 +- .../crypto/LocalClientCryptoServiceImpl.java | 284 +++++------------- 3 files changed, 153 insertions(+), 365 deletions(-) diff --git a/client/app/src/main/java/io/mosip/registration/app/MainActivity.java b/client/app/src/main/java/io/mosip/registration/app/MainActivity.java index 5bdd05f4d..2bbba127a 100644 --- a/client/app/src/main/java/io/mosip/registration/app/MainActivity.java +++ b/client/app/src/main/java/io/mosip/registration/app/MainActivity.java @@ -3,12 +3,14 @@ import io.mosip.registration.clientmanager.dto.crypto.*; import androidx.appcompat.app.AppCompatActivity; +import android.annotation.SuppressLint; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; +import android.util.Log; import android.view.View; import android.widget.TextView; import android.widget.Toast; @@ -27,6 +29,9 @@ public class MainActivity extends AppCompatActivity { private boolean mStopLoop; TextView textView; + + private String endecMessage = "encode dummy text"; + private String signMessage = "sign dummy text"; private String encryption; private String signed_string; @@ -46,190 +51,95 @@ public void click_decrypt(View view) { test_verify(view); }; - public void test_encrypt(View view) { - textView.setText("Clicked Encrypt"); - try{ - Thread.sleep(2000); - } catch(InterruptedException e){ - e.printStackTrace(); - } - new Thread(new Runnable() { - @Override - public void run() { - textView.setText("Starting encryption process"); -// creating public key request - PublicKeyRequestDto publicKeyRequestDto = new PublicKeyRequestDto(); - PublicKeyResponseDto publicKeyResponseDto = localClientCryptoService.getPublicKey(publicKeyRequestDto); -// PublicKeyResponseDto publicKeyResponseDto; - try{ - Thread.sleep(2000); - }catch(InterruptedException e){ - e.printStackTrace(); - } - textView.setText("Got public key..creating cryptoRequest"); + try { + Log.i(TAG, "test_encrypt: Encrypting...." + endecMessage); + // creating public key request + PublicKeyRequestDto publicKeyRequestDto = new PublicKeyRequestDto(); + publicKeyRequestDto.setServerProfile("endec"); - CryptoRequestDto cryptoRequestDto = new CryptoRequestDto( - "This is a new message.Hoergt this workds", publicKeyResponseDto.getPublicKey()); + PublicKeyResponseDto publicKeyResponseDto = localClientCryptoService.getPublicKey(publicKeyRequestDto); + Log.i(TAG,"Got public key..creating cryptoRequest"); - CryptoResponseDto cryptoResponseDto = localClientCryptoService.encrypt(cryptoRequestDto); + CryptoRequestDto cryptoRequestDto = new CryptoRequestDto( + endecMessage, publicKeyResponseDto.getPublicKey()); - try{ - Thread.sleep(2000); - }catch(InterruptedException e){ - e.printStackTrace(); - } + CryptoResponseDto cryptoResponseDto = localClientCryptoService.encrypt(cryptoRequestDto); - textView.setText("Encryption done"); - try{ - Thread.sleep(2000); - }catch(InterruptedException e) { - e.printStackTrace(); - } - textView.setText(cryptoResponseDto.getValue()); - encryption = cryptoResponseDto.getValue(); - } - }).start(); + Log.i(TAG, "test_encrypt: Encryption completed"); + + textView.setText("Encrypted message is : " + cryptoResponseDto.getValue() ); + encryption = cryptoResponseDto.getValue(); + } catch (Exception e) { + Log.e(TAG, "test_encrypt: Encryption Failed ", e); + } } public void test_decrypt(View view) { + try { + Log.i(TAG, "test_decrypt: Decrypting...."); + PublicKeyRequestDto publicKeyRequestDto = new PublicKeyRequestDto(); + publicKeyRequestDto.setServerProfile("endec"); + PublicKeyResponseDto publicKeyResponseDto = localClientCryptoService.getPublicKey(publicKeyRequestDto); - new Thread(new Runnable() { - @Override - public void run() { - try { - PublicKeyRequestDto publicKeyRequestDto=new PublicKeyRequestDto(); - PublicKeyResponseDto publicKeyResponseDto=localClientCryptoService.getPublicKey(publicKeyRequestDto); -// PublicKeyResponseDto publicKeyResponseDto; - textView.setText("Got public key..creating cryptoRequest for decrypt"); - try{ - Thread.sleep(2000); - }catch(InterruptedException e){ - System.out.println(e); - } - - CryptoRequestDto cryptoRequestDto = new CryptoRequestDto(encryption, publicKeyResponseDto.getPublicKey()); - textView.setText("Decrypting......"); - try{ - Thread.sleep(2000); - }catch(InterruptedException e){ - System.out.println(e); - } - - CryptoResponseDto cryptoResponseDto=localClientCryptoService.decrypt(cryptoRequestDto); - System.out.println(cryptoResponseDto.getValue()); - textView.setText("Decrypted message is : "+cryptoResponseDto.getValue() ); - - try{ - Thread.sleep(2000); - }catch(InterruptedException e){ - System.out.println(e); - } - - } catch(Exception ex) { - ex.printStackTrace(); - } + CryptoRequestDto cryptoRequestDto = new CryptoRequestDto(encryption, publicKeyResponseDto.getPublicKey()); + Log.i(TAG,"Got public key..creating cryptoRequest"); - textView.setText("Clicked Decrypt"); - } - }).start(); + CryptoResponseDto cryptoResponseDto=localClientCryptoService.decrypt(cryptoRequestDto); + Log.i(TAG, "test_decrypt: Decryption Completed"); + + textView.setText("Decrypted message is : " + cryptoResponseDto.getValue() ); + + + } catch(Exception e) { + Log.e(TAG, "test_decrypt: Decryption Failed ", e); + } } - // click_sign public void test_sign(View view){ - new Thread(new Runnable() { - @Override - public void run() { - try { - textView.setText("Clicked Sign Data.Data is: message to sign"); - try{ - Thread.sleep(2000); - }catch(InterruptedException e){ - System.out.println(e); - } - - textView.setText("Creating Sign Request "); - try{ - Thread.sleep(2000); - }catch(InterruptedException e){ - System.out.println(e); - } - - SignRequestDto signRequestDto=new SignRequestDto("message to sign"); - SignResponseDto signResponseDto=localClientCryptoService.sign(signRequestDto); - signed_string=signResponseDto.getData(); - - textView.setText("Signature Generated for string"); - try{ - Thread.sleep(2000); - }catch(InterruptedException e){ - System.out.println(e); - } - - textView.setText("Signature is: "+ signed_string); - try{ - Thread.sleep(2000); - }catch(InterruptedException e){ - System.out.println(e); - } + try { + Log.i(TAG, "test_sign: Signing...." + signMessage); + Log.i(TAG, "test_sign: Creating Sign Request "); + SignRequestDto signRequestDto = new SignRequestDto(signMessage); - } - catch (Exception ex){ - ex.printStackTrace(); - } + SignResponseDto signResponseDto = localClientCryptoService.sign(signRequestDto); + signed_string=signResponseDto.getData(); - } - }).start(); + Log.i(TAG, "test_sign: Signing completed"); + textView.setText("Signature is: "+ signed_string); + } + catch (Exception e) { + Log.e(TAG, "test_sign: Signing Failed", e); + } } - - // verifying - // click_verify public void test_verify(View view){ + try{ + Log.i(TAG, "test_verify: SignVerifying...."); + PublicKeyRequestDto publicKeyRequestDto = new PublicKeyRequestDto(); + publicKeyRequestDto.setServerProfile("sign"); + PublicKeyResponseDto publicKeyResponseDto = localClientCryptoService.getPublicKey(publicKeyRequestDto); + Log.i(TAG, "test_verify: Got public key..verifying signed data"); - new Thread(new Runnable() { - @Override - public void run() { - try{ - PublicKeyRequestDto publicKeyRequestDto=new PublicKeyRequestDto(); - PublicKeyResponseDto publicKeyResponseDto=localClientCryptoService.getPublicKey(publicKeyRequestDto); -// PublicKeyResponseDto publicKeyResponseDto; - textView.setText("Got public key..verifying signed data"); - try{ - Thread.sleep(2000); - }catch(InterruptedException e){ - System.out.println(e); - } - - - SignVerifyRequestDto signVerifyRequestDto=new SignVerifyRequestDto("message to sign",signed_string,publicKeyResponseDto.getPublicKey()); - SignVerifyResponseDto signVerifyResponseDto=localClientCryptoService.verifySign(signVerifyRequestDto); - - textView.setText("Verified Data"); - try{ - Thread.sleep(2000); - }catch(InterruptedException e){ - System.out.println(e); - } - - if(signVerifyResponseDto.isVerified()){ - textView.setText("Data is correctly signed and matching"); - } - else{ - textView.setText("Incorrect Signature"); - } - - }catch(Exception ex){ - ex.printStackTrace(); - } + SignVerifyRequestDto signVerifyRequestDto=new SignVerifyRequestDto(signMessage, signed_string, publicKeyResponseDto.getPublicKey()); + SignVerifyResponseDto signVerifyResponseDto=localClientCryptoService.verifySign(signVerifyRequestDto); + Log.i(TAG, "test_verify: Verification Completed"); + + if(signVerifyResponseDto.isVerified()){ + textView.setText("Data is correctly signed and matching"); + } + else{ + textView.setText("Incorrect Signature"); } - }).start(); + }catch(Exception e){ + Log.e(TAG, "test_verify: SignVerification Failed ", e); + } } diff --git a/client/clientmanager/src/main/assets/config.properties b/client/clientmanager/src/main/assets/config.properties index ea25bdeb4..5a79313e4 100644 --- a/client/clientmanager/src/main/assets/config.properties +++ b/client/clientmanager/src/main/assets/config.properties @@ -1,6 +1,10 @@ #----------------------- Crypto -------------------------------------------------- #Crypto asymmetric algorithm name mosip.kernel.crypto.asymmetric-algorithm-name=RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING +#Crypto asymmetric algorithm block mode +mosip.kernel.crypto.asymmetric-algorithm-block-mode=ECB +#Crypto asymmetric algorithm padding scheme +mosip.kernel.crypto.asymmetric-algorithm-padding-scheme=OAEPPadding #Crypto symmetric algorithm name mosip.kernel.crypto.symmetric-algorithm-name=AES/GCM/NoPadding #Keygenerator asymmetric algorithm name @@ -22,6 +26,8 @@ mosip.kernel.crypto.hash-symmetric-key-length=256 #No of iterations in hash mosip.kernel.crypto.hash-iteration=100000 #Sign algo name -mosip.kernel.crypto.sign-algorithm-name=RS256 +mosip.kernel.crypto.sign-algorithm-name=SHA256withRSA +#Sign algo padding scheme +mosip.kernel.crypto.sign-algorithm-padding-scheme=PKCS1 #Certificate Sign algo name mosip.kernel.certificate.sign.algorithm=SHA256withRSA \ No newline at end of file diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java index a61ba7ad0..45202e287 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java @@ -80,17 +80,16 @@ public class LocalClientCryptoServiceImpl extends Service implements ClientCrypt // asymmetric encryption details together----------------------------- private static String CRYPTO_ASYMMETRIC_ALGORITHM; - private static String KEYGEN_ASYMMETRIC_ALGORITHM; private static String KEYGEN_ASYMMETRIC_ALGO_BLOCK; private static String KEYGEN_ASYMMETRIC_ALGO_PAD; + private static String KEYGEN_ASYMMETRIC_ALGORITHM; + private static String KEYGEN_ASYMMETRIC_ALGO_SIGN_PAD; private static int KEYGEN_ASYMMETRIC_KEY_LENGTH; // symmetric encryption details together----------------------------- private static String CRYPTO_SYMMETRIC_ALGORITHM; private static String KEYGEN_SYMMETRIC_ALGORITHM; - private static String KEYGEN_SYMMETRIC_ALGO_BLOCK; - private static String KEYGEN_SYMMETRIC_ALGO_PAD; private static int KEYGEN_SYMMETRIC_KEY_LENGTH; private static int CRYPTO_GCM_TAG_LENGTH; @@ -100,6 +99,7 @@ public class LocalClientCryptoServiceImpl extends Service implements ClientCrypt private static int IV_LENGTH = 12; private static int AAD_LENGTH = 32; + private static String CRYPTO_HASH_ALGORITHM; private static int CRYPTO_HASH_SYMMETRIC_KEY_LENGTH; private static int CRYPTO_HASH_ITERATION; @@ -107,11 +107,8 @@ public class LocalClientCryptoServiceImpl extends Service implements ClientCrypt private static String CERTIFICATE_SIGN_ALGORITHM; private static final String ANDROID_KEY_STORE = "AndroidKeyStore"; - private static final String PRIVATE_ALIAS = "PRIVATE_ALIAS"; - private static final String SECRET_ALIAS = "SECRET_ALIAS"; - private static final String SIGN_ALIAS = "SIGN_ALIAS"; - - private static String KEYS_DIR = "mosipkeys"; + private static final String ENDEC_ALIAS = "ENDEC"; + private static final String SIGN_ALIAS = "SIGN"; private static SecureRandom secureRandom = null; @@ -129,32 +126,18 @@ public LocalClientCryptoServiceImpl getServiceInstance(){ @Inject public LocalClientCryptoServiceImpl() { - Log.d(TAG, "LocalClientCryptoServiceImpl: Constructor call successful"); + Log.i(TAG, "LocalClientCryptoServiceImpl: Constructor call successful"); } public void initLocalClientCryptoService() { context = getApplicationContext(); initializeClientSecurity(); - try { - // keys do not exist - if(!doesKeysExists()) { - Log.e(TAG, "LocalClientCryptoServiceImpl: Keys do not exist. Generating keys "); - genSecretKey(); - genPrivPubKey(); + genSignKey(); + genEnDecKey(); - } - else { - Log.e(TAG, "LocalClientCryptoServiceImpl: Keys exist "); - } - - } catch (Exception ex) { - ex.printStackTrace(); - } - - - Log.e(TAG, "LocalClientCryptoServiceImpl: Initialization call successful"); + Log.i(TAG, "initLocalClientCryptoService: Initialization call successful"); } // ON BIND BINDER FOR MAIN CLASS HERE @@ -203,9 +186,10 @@ public void onRebind(Intent intent) { private void initializeClientSecurity() { - // get context from main activity - Log.d(TAG, "LocalClientCryptoServiceImpl: Initializating"); + Log.i(TAG, "LocalClientCryptoServiceImpl: Initializing"); CRYPTO_ASYMMETRIC_ALGORITHM = ConfigService.getProperty("mosip.kernel.crypto.asymmetric-algorithm-name",context); + KEYGEN_ASYMMETRIC_ALGO_BLOCK = ConfigService.getProperty("mosip.kernel.crypto.asymmetric-algorithm-block-mode",context); + KEYGEN_ASYMMETRIC_ALGO_PAD = ConfigService.getProperty("mosip.kernel.crypto.asymmetric-algorithm-padding-scheme",context); CRYPTO_SYMMETRIC_ALGORITHM = ConfigService.getProperty("mosip.kernel.crypto.symmetric-algorithm-name",context); KEYGEN_ASYMMETRIC_ALGORITHM = ConfigService.getProperty("mosip.kernel.keygenerator.asymmetric-algorithm-name",context); KEYGEN_SYMMETRIC_ALGORITHM = ConfigService.getProperty("mosip.kernel.keygenerator.symmetric-algorithm-name",context); @@ -221,90 +205,57 @@ private void initializeClientSecurity() { CRYPTO_HASH_ITERATION = Integer.parseInt( ConfigService.getProperty("mosip.kernel.crypto.hash-iteration",context)); CRYPTO_SIGN_ALGORITHM = ConfigService.getProperty("mosip.kernel.crypto.sign-algorithm-name",context); + KEYGEN_ASYMMETRIC_ALGO_SIGN_PAD = ConfigService.getProperty("mosip.kernel.crypto.sign-algorithm-padding-scheme",context); CERTIFICATE_SIGN_ALGORITHM = ConfigService.getProperty("mosip.kernel.certificate.sign.algorithm",context); - base64encoder = Base64.getEncoder(); base64decoder = Base64.getDecoder(); } - private void genSecretKey() { - KEYGEN_ASYMMETRIC_ALGO_BLOCK=KeyProperties.BLOCK_MODE_ECB; - KEYGEN_ASYMMETRIC_ALGO_PAD=KeyProperties.ENCRYPTION_PADDING_RSA_OAEP; - + private void genSignKey() { try { KeyPairGenerator kpg = KeyPairGenerator.getInstance( KEYGEN_ASYMMETRIC_ALGORITHM, ANDROID_KEY_STORE); final KeyGenParameterSpec keyPairGenParameterSpec = new KeyGenParameterSpec.Builder( - SECRET_ALIAS, - KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) - .setBlockModes(KEYGEN_ASYMMETRIC_ALGO_BLOCK) + SIGN_ALIAS, + KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY) .setKeySize(KEYGEN_ASYMMETRIC_KEY_LENGTH) - .setEncryptionPaddings(KEYGEN_ASYMMETRIC_ALGO_PAD) -// .setUserAuthenticationRequired(true) + .setSignaturePaddings(KEYGEN_ASYMMETRIC_ALGO_SIGN_PAD) .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512) .build(); kpg.initialize(keyPairGenParameterSpec); KeyPair kp = kpg.generateKeyPair(); + Log.i(TAG, "genSignKey: Generated signing private key successfully " + + base64encoder.encodeToString(kp.getPublic().getEncoded())); - PublicKey publicKey = kp.getPublic(); - - Log.e(TAG, "genSecretKey: Generated private key successfully " + kp.getPublic()); - - KeyGenerator keyGen = KeyGenerator.getInstance(KEYGEN_SYMMETRIC_ALGORITHM); - keyGen.init(KEYGEN_SYMMETRIC_KEY_LENGTH); - SecretKey mosipSecretKey = keyGen.generateKey(); - - Log.e(TAG, "genSecretKey: Generated mosip key successfully " + mosipSecretKey.getEncoded()); - - final Cipher cipher_asymmetric = Cipher.getInstance(CRYPTO_ASYMMETRIC_ALGORITHM); - OAEPParameterSpec spec = new OAEPParameterSpec( - "SHA-256", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT); - cipher_asymmetric.init(Cipher.ENCRYPT_MODE, publicKey, spec); - - byte[] secretKeyEncryption = cipher_asymmetric.doFinal(mosipSecretKey.getEncoded()); - Log.e(TAG, "genSecretKey: Generated secret key encryption"); - - Log.e(TAG, "getSecretKey: Key length " + (secretKeyEncryption.length)); - createKeyFile(getKeysDirPath(), secretKeyEncryption); - - Log.e(TAG, "genSecretKey: Generated secret key successfully "); - - } catch(Exception ex) { - ex.printStackTrace(); + } catch(Exception e) { + Log.e(TAG, "genSignKey: Sign key generation failed ", e); } } - private void genPrivPubKey() { - - KEYGEN_ASYMMETRIC_ALGO_BLOCK = KeyProperties.BLOCK_MODE_ECB; - KEYGEN_ASYMMETRIC_ALGO_PAD = KeyProperties.ENCRYPTION_PADDING_RSA_OAEP; - KEYGEN_ASYMMETRIC_ALGO_SIGN_PAD = KeyProperties.SIGNATURE_PADDING_RSA_PKCS1; - + private void genEnDecKey() { try { - // lot of errors in asymmetric part KeyPairGenerator kpg = KeyPairGenerator.getInstance( KEYGEN_ASYMMETRIC_ALGORITHM, ANDROID_KEY_STORE); final KeyGenParameterSpec keyPairGenParameterSpec = new KeyGenParameterSpec.Builder( - PRIVATE_ALIAS, - KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY | + ENDEC_ALIAS, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) .setBlockModes(KEYGEN_ASYMMETRIC_ALGO_BLOCK) .setKeySize(KEYGEN_ASYMMETRIC_KEY_LENGTH) .setEncryptionPaddings(KEYGEN_ASYMMETRIC_ALGO_PAD) - .setSignaturePaddings(KEYGEN_ASYMMETRIC_ALGO_SIGN_PAD) .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512) .build(); kpg.initialize(keyPairGenParameterSpec); KeyPair kp = kpg.generateKeyPair(); - Log.e(TAG, "genPrivateKey: Generated private key successfully " + base64encoder.encodeToString(kp.getPublic().getEncoded())); + Log.i(TAG, "genEnDecKey: Generated encryption private key successfully " + + base64encoder.encodeToString(kp.getPublic().getEncoded())); - } catch(Exception ex) { - ex.printStackTrace(); + } catch(Exception e) { + Log.e(TAG, "genEnDecKey: Encryption key generation failed ", e); } } @@ -314,7 +265,7 @@ public SignResponseDto sign(SignRequestDto signRequestDto) { byte[] dataToSign = base64decoder.decode(base64encoder.encodeToString(signRequestDto.getData().getBytes())); try { - PrivateKey privateKey = getPrivateKey(); + PrivateKey privateKey = getSignPrivateKey(); Signature sign = Signature.getInstance(CERTIFICATE_SIGN_ALGORITHM); sign.initSign(privateKey); sign.update(dataToSign); @@ -323,8 +274,8 @@ public SignResponseDto sign(SignRequestDto signRequestDto) { signResponseDto.setData(base64encoder.encodeToString(signedData)); return signResponseDto; - } catch (Exception ex) { - ex.printStackTrace(); + } catch (Exception e) { + Log.e(TAG, "sign: Signing Failed ", e); } return null; } @@ -350,8 +301,8 @@ public SignVerifyResponseDto verifySign(SignVerifyRequestDto signVerifyRequestDt signVerifyResponseDto.setVerified(result); return signVerifyResponseDto; } - catch(Exception ex) { - ex.printStackTrace(); + catch(Exception e) { + Log.e(TAG, "verifySign: Sign Verification Failed", e); } return null; } @@ -367,41 +318,39 @@ public CryptoResponseDto encrypt(CryptoRequestDto cryptoRequestDto) { X509EncodedKeySpec keySpec = new X509EncodedKeySpec(public_key); KeyFactory kf = KeyFactory.getInstance(KEYGEN_ASYMMETRIC_ALGORITHM); PublicKey publicKey = kf.generatePublic(keySpec); - Log.e(TAG, "encrypt: Read public key obj"); - SecretKey mosipSecretKey = getSecretKey(); - Log.e(TAG, "encrypt: Read mosip key successfully " + mosipSecretKey.getEncoded()); - // symmetric encryption of data----------------------------------------------------- - final Cipher cipher_symmetric = Cipher.getInstance(CRYPTO_SYMMETRIC_ALGORITHM); + KeyGenerator keyGen = KeyGenerator.getInstance(KEYGEN_SYMMETRIC_ALGORITHM); + keyGen.init(KEYGEN_SYMMETRIC_KEY_LENGTH); + SecretKey mosipSecretKey = keyGen.generateKey(); + + // symmetric encryption of data--------------------------------------------------------- + final Cipher cipher_symmetric = Cipher.getInstance(CRYPTO_SYMMETRIC_ALGORITHM); cipher_symmetric.init(Cipher.ENCRYPT_MODE, mosipSecretKey); byte[] iv = cipher_symmetric.getIV(); byte[] aad = generateRandomBytes(AAD_LENGTH); cipher_symmetric.updateAAD(aad); byte[] data_encryption = cipher_symmetric.doFinal(dataToEncrypt); - Log.e(TAG, "encrypt: Generated message encryption" + data_encryption); - // asymmetric encryption of secret key---------------------------------------------------- + // asymmetric encryption of secret key-------------------------------------------------- final Cipher cipher_asymmetric = Cipher.getInstance(CRYPTO_ASYMMETRIC_ALGORITHM); OAEPParameterSpec spec = new OAEPParameterSpec( "SHA-256", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT); - cipher_asymmetric.init(Cipher.ENCRYPT_MODE, publicKey,spec); + cipher_asymmetric.init(Cipher.ENCRYPT_MODE, publicKey, spec); byte[] key_encryption = cipher_asymmetric.doFinal(mosipSecretKey.getEncoded()); - Log.e(TAG, "encrypt: Generated secret key encryption"); - // storing iv and encryption in encrypted_data + // constructing key, iv, add and encryption stream-------------------------------------- ByteArrayOutputStream outputStream = new ByteArrayOutputStream( ); outputStream.write(key_encryption); outputStream.write(iv); outputStream.write(aad); outputStream.write(data_encryption); - // need to add aad + byte[] encrypted_key_iv_data = outputStream.toByteArray(); - Log.e(TAG, "encrypt: Generated encrypted data"); cryptoResponseDto.setValue(base64encoder.encodeToString(encrypted_key_iv_data)); return cryptoResponseDto; - } catch(Exception ex) { - ex.printStackTrace(); + } catch(Exception e) { + Log.e(TAG, "encrypt: Encryption failed ", e); } return null; @@ -419,7 +368,7 @@ public CryptoResponseDto decrypt(CryptoRequestDto cryptoRequestDto) { byte[] encrypted_data = Arrays.copyOfRange(dataToDecrypt, KEYGEN_SYMMETRIC_KEY_LENGTH+IV_LENGTH+AAD_LENGTH, dataToDecrypt.length); try { - PrivateKey privateKey = getPrivateKey(); + PrivateKey privateKey = getEnDecPrivateKey(); // asymmetric decryption of secret key---------------------------------------------------- final Cipher cipher_asymmetric = Cipher.getInstance(CRYPTO_ASYMMETRIC_ALGORITHM); @@ -437,8 +386,8 @@ public CryptoResponseDto decrypt(CryptoRequestDto cryptoRequestDto) { String decodedString = new String(decodedBytes); cryptoResponseDto.setValue(decodedString); return cryptoResponseDto; - } catch(Exception ex) { - ex.printStackTrace(); + } catch(Exception e) { + Log.e(TAG, "decrypt: Decryption failed", e); } return null; } @@ -448,138 +397,61 @@ public PublicKeyResponseDto getPublicKey(PublicKeyRequestDto publicKeyRequestDto PublicKeyResponseDto publicKeyResponseDto = new PublicKeyResponseDto(); try { - PublicKey publicKey = getPublicKey(); - String public_key = base64encoder.encodeToString(publicKey.getEncoded()); - Log.e(TAG, "getPublicKey: Public key accessed " + public_key); - publicKeyResponseDto.setPublicKey(public_key); - return publicKeyResponseDto; - } catch(Exception ex) { - ex.printStackTrace(); + String keyRequest = publicKeyRequestDto.getServerProfile(); + Log.i(TAG, "getPublicKey: Public key accessed for " + keyRequest); + if(keyRequest == "sign") { + PublicKey publicKey = getSignPublicKey(); + Log.i(TAG, "getPublicKey: Sign Public key accessed "); + String public_key = base64encoder.encodeToString(publicKey.getEncoded()); + publicKeyResponseDto.setPublicKey(public_key); + return publicKeyResponseDto; + } + else if(keyRequest == "endec") { + PublicKey publicKey = getEnDecPublicKey(); + Log.i(TAG, "getPublicKey: EnDec Public key accessed "); + String public_key = base64encoder.encodeToString(publicKey.getEncoded()); + publicKeyResponseDto.setPublicKey(public_key); + return publicKeyResponseDto; + } + } catch(Exception e) { + Log.e(TAG, "getPublicKey: Public key access failed ", e); } return null; } - private boolean doesKeysExists() throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableEntryException { + // get endec private key from keystore + private PrivateKey getEnDecPrivateKey() throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableEntryException { KeyStore ks = KeyStore.getInstance(ANDROID_KEY_STORE); ks.load(null); - - // check if secret key exists - KeyStore.Entry entry = ks.getEntry(SECRET_ALIAS, null); - if (!(entry instanceof KeyStore.SecretKeyEntry)) { - return false; - } - Log.e(TAG, "doesKeysExists: Secret key exists"); - - // check if private key exists - entry = ks.getEntry(PRIVATE_ALIAS, null); - if (!(entry instanceof KeyStore.PrivateKeyEntry)) { - return false; - } - Log.e(TAG, "doesKeysExists: Private key exists"); - - File file = new File(context.getFilesDir(),getKeysDirPath()); - if(!file.exists()) { - file.createNewFile(); - Log.e(TAG, "doesKeysExists: File created..."); - return false; - } - Log.e(TAG, "doesKeysExists: Mosip key exists"); - return true; + return (PrivateKey) ks.getKey(ENDEC_ALIAS, null); } - private String getKeysDirPath() { -// return KEYS_DIR + File.separator + SECRET_ALIAS; - return SECRET_ALIAS; - } - - // create a key file to store the encrypted secret key - private void createKeyFile(String keyDir, byte[] key) throws IOException { - - String keyEncoded = Base64.getEncoder().encodeToString(key); - try { - File file = new File(context.getFilesDir(), getKeysDirPath()); - if(!file.exists()) { - try { - file.createNewFile(); - Log.e(TAG, "createKeyFile: File"); - } catch (AccessDeniedException ex) { - Log.e(TAG, "createKeyFile: Access Denied", ex); - } - } - FileOutputStream stream = new FileOutputStream(file); - try { - stream.write(keyEncoded.getBytes()); - } finally { - stream.close(); - } - - Log.e(TAG, "createKeyFile: key " + keyEncoded); - } catch (Exception ex) { - ex.printStackTrace(); - } - } - - - // get secret key from keystore - private SecretKey getSecretKey() throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableEntryException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { + // get endec public key from keystore + private PublicKey getEnDecPublicKey() throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableEntryException { KeyStore ks = KeyStore.getInstance(ANDROID_KEY_STORE); ks.load(null); - PrivateKey privateKey = (PrivateKey) ks.getKey(SECRET_ALIAS, null); - - String keyEncoded = ""; - File file = new File(context.getFilesDir(), getKeysDirPath()); - if(file.exists()) { - int length = (int) file.length(); - byte[] bytes = new byte[length]; - FileInputStream in = new FileInputStream(file); - try { - in.read(bytes); - } finally { - in.close(); - } - keyEncoded += new String(bytes); - Log.e(TAG, "createKeyFile: key " + keyEncoded); - } - else { - Log.e(TAG, "getSecretKey: File not exists"); - } - - byte[] secretKeyEncryption = base64decoder.decode(keyEncoded); - Log.e(TAG, "getSecretKey: Key length " + (secretKeyEncryption.length)); - - - final Cipher cipher_asymmetric = Cipher.getInstance(CRYPTO_ASYMMETRIC_ALGORITHM); - cipher_asymmetric.init(Cipher.DECRYPT_MODE, privateKey); - - byte[] secretKeyBytes = cipher_asymmetric.doFinal(secretKeyEncryption); - Log.e(TAG, "getSecretKey: secretKeyBytes " + secretKeyBytes); - return new SecretKeySpec(secretKeyBytes, KEYGEN_SYMMETRIC_ALGORITHM); + return (PublicKey) ks.getCertificate(ENDEC_ALIAS).getPublicKey(); } - // get private key from keystore - private PrivateKey getPrivateKey() throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableEntryException { + // get sign private key from keystore + private PrivateKey getSignPrivateKey() throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableEntryException { KeyStore ks = KeyStore.getInstance(ANDROID_KEY_STORE); ks.load(null); - return (PrivateKey) ks.getKey(PRIVATE_ALIAS, null); + return (PrivateKey) ks.getKey(SIGN_ALIAS, null); } - // get public key from keystore - private PublicKey getPublicKey() throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableEntryException { + // get sign public key from keystore + private PublicKey getSignPublicKey() throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableEntryException { KeyStore ks = KeyStore.getInstance(ANDROID_KEY_STORE); ks.load(null); - return (PublicKey) ks.getCertificate(PRIVATE_ALIAS).getPublicKey(); + return (PublicKey) ks.getCertificate(SIGN_ALIAS).getPublicKey(); } - // random byte generation for AAD + // random byte generation public static byte[] generateRandomBytes(int length) { - SecureRandom secureRandom = new SecureRandom(); - byte[] bytes = new byte[length]; secureRandom.nextBytes(bytes); return bytes; } - - - } \ No newline at end of file From 4bf3815635e051ce142ab6f81bf42f63f47f7ffe Mon Sep 17 00:00:00 2001 From: EricJohnEastwood Date: Tue, 28 Sep 2021 12:51:07 +0530 Subject: [PATCH 20/27] Cleanup LocalClientCryptoServiceImpl --- .../io/mosip/registration/app/MainActivity.java | 4 ++-- .../src/main/assets/config.properties | 6 +++++- .../crypto/LocalClientCryptoServiceImpl.java | 16 ++++++++++------ 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/client/app/src/main/java/io/mosip/registration/app/MainActivity.java b/client/app/src/main/java/io/mosip/registration/app/MainActivity.java index 2bbba127a..cfae6dd78 100644 --- a/client/app/src/main/java/io/mosip/registration/app/MainActivity.java +++ b/client/app/src/main/java/io/mosip/registration/app/MainActivity.java @@ -45,10 +45,10 @@ protected void onCreate(Bundle savedInstanceState) { bindService(); } public void click_encrypt(View view) { - test_sign(view); + test_encrypt(view); }; public void click_decrypt(View view) { - test_verify(view); + test_decrypt(view); }; public void test_encrypt(View view) { diff --git a/client/clientmanager/src/main/assets/config.properties b/client/clientmanager/src/main/assets/config.properties index 5a79313e4..cab3db4d7 100644 --- a/client/clientmanager/src/main/assets/config.properties +++ b/client/clientmanager/src/main/assets/config.properties @@ -15,6 +15,10 @@ mosip.kernel.keygenerator.symmetric-algorithm-name=AES mosip.kernel.keygenerator.asymmetric-key-length=2048 #Symmetric algorithm key length mosip.kernel.keygenerator.symmetric-key-length=256 +#Crypto symmetric IV length +mosip.kernel.crypto.symmetric-algorithm-iv-length=12 +#Crypto symmetric AAD length +mosip.kernel.crypto.symmetric-algorithm-aad-length=32 #Encrypted data and encrypted symmetric key separator mosip.kernel.data-key-splitter=#KEY_SPLITTER# #GCM tag length @@ -30,4 +34,4 @@ mosip.kernel.crypto.sign-algorithm-name=SHA256withRSA #Sign algo padding scheme mosip.kernel.crypto.sign-algorithm-padding-scheme=PKCS1 #Certificate Sign algo name -mosip.kernel.certificate.sign.algorithm=SHA256withRSA \ No newline at end of file +mosip.kernel.certificate.sign.algorithm=SHA256withRSA diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java index 45202e287..286cb26d9 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java @@ -96,8 +96,8 @@ public class LocalClientCryptoServiceImpl extends Service implements ClientCrypt // need to read aad and iv length from config files----- - private static int IV_LENGTH = 12; - private static int AAD_LENGTH = 32; + private static int CRYPTO_SYMMETRIC_IV_LENGTH; + private static int CRYPTO_SYMMETRIC_AAD_LENGTH; private static String CRYPTO_HASH_ALGORITHM; @@ -197,6 +197,10 @@ private void initializeClientSecurity() { ConfigService.getProperty("mosip.kernel.keygenerator.asymmetric-key-length",context)); KEYGEN_SYMMETRIC_KEY_LENGTH = Integer.parseInt( ConfigService.getProperty("mosip.kernel.keygenerator.symmetric-key-length",context)); + CRYPTO_SYMMETRIC_IV_LENGTH = Integer.parseInt( + ConfigService.getProperty("mosip.kernel.crypto.symmetric-algorithm-iv-length",context)); + CRYPTO_SYMMETRIC_AAD_LENGTH = Integer.parseInt( + ConfigService.getProperty("mosip.kernel.crypto.symmetric-algorithm-aad-length",context)); CRYPTO_GCM_TAG_LENGTH = Integer.parseInt( ConfigService.getProperty("mosip.kernel.crypto.gcm-tag-length",context)); CRYPTO_HASH_ALGORITHM = ConfigService.getProperty("mosip.kernel.crypto.hash-algorithm-name",context); @@ -327,7 +331,7 @@ public CryptoResponseDto encrypt(CryptoRequestDto cryptoRequestDto) { final Cipher cipher_symmetric = Cipher.getInstance(CRYPTO_SYMMETRIC_ALGORITHM); cipher_symmetric.init(Cipher.ENCRYPT_MODE, mosipSecretKey); byte[] iv = cipher_symmetric.getIV(); - byte[] aad = generateRandomBytes(AAD_LENGTH); + byte[] aad = generateRandomBytes(CRYPTO_SYMMETRIC_AAD_LENGTH); cipher_symmetric.updateAAD(aad); byte[] data_encryption = cipher_symmetric.doFinal(dataToEncrypt); @@ -363,9 +367,9 @@ public CryptoResponseDto decrypt(CryptoRequestDto cryptoRequestDto) { byte[] public_key = base64decoder.decode(cryptoRequestDto.getPublicKey()); byte[] encryptedSecretKey = Arrays.copyOfRange(dataToDecrypt, 0, KEYGEN_SYMMETRIC_KEY_LENGTH); - byte[] iv = Arrays.copyOfRange(dataToDecrypt, KEYGEN_SYMMETRIC_KEY_LENGTH, KEYGEN_SYMMETRIC_KEY_LENGTH+IV_LENGTH); - byte[] aad = Arrays.copyOfRange(dataToDecrypt,KEYGEN_SYMMETRIC_KEY_LENGTH+IV_LENGTH, KEYGEN_SYMMETRIC_KEY_LENGTH+IV_LENGTH+AAD_LENGTH); - byte[] encrypted_data = Arrays.copyOfRange(dataToDecrypt, KEYGEN_SYMMETRIC_KEY_LENGTH+IV_LENGTH+AAD_LENGTH, dataToDecrypt.length); + byte[] iv = Arrays.copyOfRange(dataToDecrypt, KEYGEN_SYMMETRIC_KEY_LENGTH, KEYGEN_SYMMETRIC_KEY_LENGTH+CRYPTO_SYMMETRIC_IV_LENGTH); + byte[] aad = Arrays.copyOfRange(dataToDecrypt,KEYGEN_SYMMETRIC_KEY_LENGTH+CRYPTO_SYMMETRIC_IV_LENGTH, KEYGEN_SYMMETRIC_KEY_LENGTH+CRYPTO_SYMMETRIC_IV_LENGTH+CRYPTO_SYMMETRIC_AAD_LENGTH); + byte[] encrypted_data = Arrays.copyOfRange(dataToDecrypt, KEYGEN_SYMMETRIC_KEY_LENGTH+CRYPTO_SYMMETRIC_IV_LENGTH+CRYPTO_SYMMETRIC_AAD_LENGTH, dataToDecrypt.length); try { PrivateKey privateKey = getEnDecPrivateKey(); From edaf467de92dddeda943ebcf8b9d6e35f1bc776e Mon Sep 17 00:00:00 2001 From: EricJohnEastwood Date: Tue, 28 Sep 2021 15:19:13 +0530 Subject: [PATCH 21/27] Update buttons --- .../mosip/registration/app/MainActivity.java | 35 +++++--- .../app/src/main/res/layout/activity_main.xml | 83 +++++++++++++++++-- .../src/main/assets/config.properties | 4 + .../crypto/LocalClientCryptoServiceImpl.java | 6 +- 4 files changed, 105 insertions(+), 23 deletions(-) diff --git a/client/app/src/main/java/io/mosip/registration/app/MainActivity.java b/client/app/src/main/java/io/mosip/registration/app/MainActivity.java index cfae6dd78..77760cee1 100644 --- a/client/app/src/main/java/io/mosip/registration/app/MainActivity.java +++ b/client/app/src/main/java/io/mosip/registration/app/MainActivity.java @@ -3,7 +3,6 @@ import io.mosip.registration.clientmanager.dto.crypto.*; import androidx.appcompat.app.AppCompatActivity; -import android.annotation.SuppressLint; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -12,8 +11,8 @@ import android.os.IBinder; import android.util.Log; import android.view.View; +import android.widget.EditText; import android.widget.TextView; -import android.widget.Toast; import io.mosip.registration.clientmanager.service.crypto.LocalClientCryptoServiceImpl; @@ -28,10 +27,12 @@ public class MainActivity extends AppCompatActivity { private ServiceConnection serviceConnection; private boolean mStopLoop; - TextView textView; + EditText messageInput; + TextView endecTextView; + TextView signTextView; - private String endecMessage = "encode dummy text"; - private String signMessage = "sign dummy text"; + private String endecMessage; + private String signMessage; private String encryption; private String signed_string; @@ -40,19 +41,26 @@ public class MainActivity extends AppCompatActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - textView = (TextView) findViewById(R.id.testerView); + messageInput = (EditText) findViewById(R.id.msg_input); + endecTextView = (TextView) findViewById(R.id.EnDecTextView); + signTextView = (TextView) findViewById(R.id.SignTextView); serviceIntent= new Intent(getApplicationContext(), LocalClientCryptoServiceImpl.class); bindService(); } public void click_encrypt(View view) { test_encrypt(view); }; - public void click_decrypt(View view) { - test_decrypt(view); + public void click_decrypt(View view) { test_decrypt(view); }; + + public void click_sign(View view) { + test_sign(view); }; + public void click_verify(View view) { test_verify(view); }; + public void test_encrypt(View view) { try { + endecMessage = messageInput.getText().toString(); Log.i(TAG, "test_encrypt: Encrypting...." + endecMessage); // creating public key request PublicKeyRequestDto publicKeyRequestDto = new PublicKeyRequestDto(); @@ -68,7 +76,7 @@ public void test_encrypt(View view) { Log.i(TAG, "test_encrypt: Encryption completed"); - textView.setText("Encrypted message is : " + cryptoResponseDto.getValue() ); + endecTextView.setText("Encrypted message is : " + cryptoResponseDto.getValue() ); encryption = cryptoResponseDto.getValue(); } catch (Exception e) { Log.e(TAG, "test_encrypt: Encryption Failed ", e); @@ -89,7 +97,7 @@ public void test_decrypt(View view) { CryptoResponseDto cryptoResponseDto=localClientCryptoService.decrypt(cryptoRequestDto); Log.i(TAG, "test_decrypt: Decryption Completed"); - textView.setText("Decrypted message is : " + cryptoResponseDto.getValue() ); + endecTextView.setText("Decrypted message is : " + cryptoResponseDto.getValue() ); } catch(Exception e) { @@ -100,6 +108,7 @@ public void test_decrypt(View view) { public void test_sign(View view){ try { + signMessage = messageInput.getText().toString(); Log.i(TAG, "test_sign: Signing...." + signMessage); Log.i(TAG, "test_sign: Creating Sign Request "); @@ -109,7 +118,7 @@ public void test_sign(View view){ signed_string=signResponseDto.getData(); Log.i(TAG, "test_sign: Signing completed"); - textView.setText("Signature is: "+ signed_string); + signTextView.setText("Signature is: "+ signed_string); } catch (Exception e) { @@ -131,10 +140,10 @@ public void test_verify(View view){ Log.i(TAG, "test_verify: Verification Completed"); if(signVerifyResponseDto.isVerified()){ - textView.setText("Data is correctly signed and matching"); + signTextView.setText("Data is correctly signed and matching"); } else{ - textView.setText("Incorrect Signature"); + signTextView.setText("Incorrect Signature"); } }catch(Exception e){ diff --git a/client/app/src/main/res/layout/activity_main.xml b/client/app/src/main/res/layout/activity_main.xml index 08a9727ba..e4b6f8950 100644 --- a/client/app/src/main/res/layout/activity_main.xml +++ b/client/app/src/main/res/layout/activity_main.xml @@ -6,11 +6,25 @@ android:layout_height="match_parent" tools:context=".MainActivity"> + + + app:layout_constraintVertical_bias="0.289" /> + app:layout_constraintVertical_bias="0.289" /> + + + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintVertical_bias="0.597" /> + + + + \ No newline at end of file diff --git a/client/clientmanager/src/main/assets/config.properties b/client/clientmanager/src/main/assets/config.properties index cab3db4d7..601dec5b8 100644 --- a/client/clientmanager/src/main/assets/config.properties +++ b/client/clientmanager/src/main/assets/config.properties @@ -5,6 +5,10 @@ mosip.kernel.crypto.asymmetric-algorithm-name=RSA/ECB/OAEPWITHSHA-256ANDMGF1PADD mosip.kernel.crypto.asymmetric-algorithm-block-mode=ECB #Crypto asymmetric algorithm padding scheme mosip.kernel.crypto.asymmetric-algorithm-padding-scheme=OAEPPadding +#Crypto asymmetric algorithm OAEP hash function +mosip.kernel.crypto.asymmetric-algorithm-message-digest-function=SHA-256 +#Crypto asymmetric algorithm OAEP mask generation function +mosip.kernel.crypto.asymmetric-algorithm-mask-generation-function=MGF1 #Crypto symmetric algorithm name mosip.kernel.crypto.symmetric-algorithm-name=AES/GCM/NoPadding #Keygenerator asymmetric algorithm name diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java index 286cb26d9..d91d616d3 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java @@ -83,6 +83,8 @@ public class LocalClientCryptoServiceImpl extends Service implements ClientCrypt private static String KEYGEN_ASYMMETRIC_ALGO_BLOCK; private static String KEYGEN_ASYMMETRIC_ALGO_PAD; private static String KEYGEN_ASYMMETRIC_ALGORITHM; + private static String CRYPTO_ASYMMETRIC_ALGO_MD; + private static String CRYPTO_ASYMMETRIC_ALGO_MGF; private static String KEYGEN_ASYMMETRIC_ALGO_SIGN_PAD; private static int KEYGEN_ASYMMETRIC_KEY_LENGTH; @@ -190,6 +192,8 @@ private void initializeClientSecurity() { CRYPTO_ASYMMETRIC_ALGORITHM = ConfigService.getProperty("mosip.kernel.crypto.asymmetric-algorithm-name",context); KEYGEN_ASYMMETRIC_ALGO_BLOCK = ConfigService.getProperty("mosip.kernel.crypto.asymmetric-algorithm-block-mode",context); KEYGEN_ASYMMETRIC_ALGO_PAD = ConfigService.getProperty("mosip.kernel.crypto.asymmetric-algorithm-padding-scheme",context); + CRYPTO_ASYMMETRIC_ALGO_MD = ConfigService.getProperty("mosip.kernel.crypto.asymmetric-algorithm-message-digest-function",context); + CRYPTO_ASYMMETRIC_ALGO_MGF = ConfigService.getProperty("mosip.kernel.crypto.asymmetric-algorithm-mask-generation-function",context); CRYPTO_SYMMETRIC_ALGORITHM = ConfigService.getProperty("mosip.kernel.crypto.symmetric-algorithm-name",context); KEYGEN_ASYMMETRIC_ALGORITHM = ConfigService.getProperty("mosip.kernel.keygenerator.asymmetric-algorithm-name",context); KEYGEN_SYMMETRIC_ALGORITHM = ConfigService.getProperty("mosip.kernel.keygenerator.symmetric-algorithm-name",context); @@ -338,7 +342,7 @@ public CryptoResponseDto encrypt(CryptoRequestDto cryptoRequestDto) { // asymmetric encryption of secret key-------------------------------------------------- final Cipher cipher_asymmetric = Cipher.getInstance(CRYPTO_ASYMMETRIC_ALGORITHM); OAEPParameterSpec spec = new OAEPParameterSpec( - "SHA-256", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT); + CRYPTO_ASYMMETRIC_ALGO_MD, CRYPTO_ASYMMETRIC_ALGO_MGF, MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT); cipher_asymmetric.init(Cipher.ENCRYPT_MODE, publicKey, spec); byte[] key_encryption = cipher_asymmetric.doFinal(mosipSecretKey.getEncoded()); From fa3d006741705243820ddadc320e047e12ebb7b6 Mon Sep 17 00:00:00 2001 From: EricJohnEastwood Date: Thu, 30 Sep 2021 23:09:51 +0530 Subject: [PATCH 22/27] Add Dependency Injection --- client/app/build.gradle | 6 +- client/app/src/main/AndroidManifest.xml | 1 + .../registration/app/BaseApplication.java | 14 ++++ .../mosip/registration/app/MainActivity.java | 54 ++------------ .../io/mosip/registration/app/OpenDialog.java | 27 ------- .../app/di/ActivityBuildersModule.java | 12 ++++ .../registration/app/di/AppComponent.java | 29 ++++++++ .../mosip/registration/app/di/AppModule.java | 40 +++++++++++ .../app/di/ClientManagerModule.java | 18 +++++ .../crypto/LocalClientCryptoServiceImpl.java | 72 +++---------------- 10 files changed, 136 insertions(+), 137 deletions(-) create mode 100644 client/app/src/main/java/io/mosip/registration/app/BaseApplication.java delete mode 100644 client/app/src/main/java/io/mosip/registration/app/OpenDialog.java create mode 100644 client/app/src/main/java/io/mosip/registration/app/di/ActivityBuildersModule.java create mode 100644 client/app/src/main/java/io/mosip/registration/app/di/AppComponent.java create mode 100644 client/app/src/main/java/io/mosip/registration/app/di/AppModule.java create mode 100644 client/app/src/main/java/io/mosip/registration/app/di/ClientManagerModule.java diff --git a/client/app/build.gradle b/client/app/build.gradle index 12d03eea4..99e3ae6e8 100644 --- a/client/app/build.gradle +++ b/client/app/build.gradle @@ -52,9 +52,11 @@ configurations { } } - - dependencies { + implementation 'com.google.dagger:dagger:2.38.1' + implementation 'com.google.dagger:dagger-android-support:2.38.1' + annotationProcessor 'com.google.dagger:dagger-compiler:2.38.1' + annotationProcessor 'com.google.dagger:dagger-android-processor:2.38.1' implementation 'androidx.appcompat:appcompat:1.3.1' implementation 'com.google.android.material:material:1.3.0' diff --git a/client/app/src/main/AndroidManifest.xml b/client/app/src/main/AndroidManifest.xml index 44a6772cf..c0249f161 100644 --- a/client/app/src/main/AndroidManifest.xml +++ b/client/app/src/main/AndroidManifest.xml @@ -3,6 +3,7 @@ package="io.mosip.registration.app"> applicationInjector() { + return DaggerAppComponent.builder().application(this).appModule(new AppModule(this)).build(); + } +} diff --git a/client/app/src/main/java/io/mosip/registration/app/MainActivity.java b/client/app/src/main/java/io/mosip/registration/app/MainActivity.java index 77760cee1..31eaa43bc 100644 --- a/client/app/src/main/java/io/mosip/registration/app/MainActivity.java +++ b/client/app/src/main/java/io/mosip/registration/app/MainActivity.java @@ -1,5 +1,6 @@ package io.mosip.registration.app; +import dagger.android.support.DaggerAppCompatActivity; import io.mosip.registration.clientmanager.dto.crypto.*; import androidx.appcompat.app.AppCompatActivity; @@ -14,18 +15,15 @@ import android.widget.EditText; import android.widget.TextView; +import javax.inject.Inject; + import io.mosip.registration.clientmanager.service.crypto.LocalClientCryptoServiceImpl; -public class MainActivity extends AppCompatActivity { +public class MainActivity extends DaggerAppCompatActivity { private static final String TAG = MainActivity.class.getSimpleName(); - private LocalClientCryptoServiceImpl localClientCryptoService; - private boolean isServiceBound; - - - private Intent serviceIntent; - private ServiceConnection serviceConnection; - private boolean mStopLoop; + @Inject + public LocalClientCryptoServiceImpl localClientCryptoService; EditText messageInput; TextView endecTextView; @@ -44,8 +42,7 @@ protected void onCreate(Bundle savedInstanceState) { messageInput = (EditText) findViewById(R.id.msg_input); endecTextView = (TextView) findViewById(R.id.EnDecTextView); signTextView = (TextView) findViewById(R.id.SignTextView); - serviceIntent= new Intent(getApplicationContext(), LocalClientCryptoServiceImpl.class); - bindService(); + } public void click_encrypt(View view) { test_encrypt(view); @@ -149,42 +146,5 @@ public void test_verify(View view){ }catch(Exception e){ Log.e(TAG, "test_verify: SignVerification Failed ", e); } - } - - - private void bindService(){ - if(serviceConnection==null){ - serviceConnection = new ServiceConnection() { - @Override - public void onServiceConnected(ComponentName className, - IBinder service) { - // Binding to LocalClientCryptoServiceImpl, cast the IBinder and - // getting LocalClientCryptoServiceImpl instance - LocalClientCryptoServiceImpl.ClientCryptoServiceBinder binder = - (LocalClientCryptoServiceImpl.ClientCryptoServiceBinder) service; - //Get instance of your service - localClientCryptoService = binder.getServiceInstance(); - localClientCryptoService.initLocalClientCryptoService(); - isServiceBound = true; - } - - @Override - public void onServiceDisconnected(ComponentName className) { - isServiceBound = false; - } - }; - } - - bindService(serviceIntent,serviceConnection, Context.BIND_AUTO_CREATE); - - } - - private void unbindService(){ - if(isServiceBound){ - unbindService(serviceConnection); - isServiceBound=false; - } - } - } \ No newline at end of file diff --git a/client/app/src/main/java/io/mosip/registration/app/OpenDialog.java b/client/app/src/main/java/io/mosip/registration/app/OpenDialog.java deleted file mode 100644 index 8903a529e..000000000 --- a/client/app/src/main/java/io/mosip/registration/app/OpenDialog.java +++ /dev/null @@ -1,27 +0,0 @@ -package io.mosip.registration.app; - -import android.app.AlertDialog; -import android.app.Dialog; -import android.content.DialogInterface; -import android.os.Bundle; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatDialog; -import androidx.appcompat.app.AppCompatDialogFragment; - -public class OpenDialog extends AppCompatDialogFragment { - @NonNull - @Override - public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - builder.setTitle("Clicked").setMessage("Continue?") - .setPositiveButton("ok", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - - } - }); - return builder.create(); - } -} diff --git a/client/app/src/main/java/io/mosip/registration/app/di/ActivityBuildersModule.java b/client/app/src/main/java/io/mosip/registration/app/di/ActivityBuildersModule.java new file mode 100644 index 000000000..16d2eb1bb --- /dev/null +++ b/client/app/src/main/java/io/mosip/registration/app/di/ActivityBuildersModule.java @@ -0,0 +1,12 @@ +package io.mosip.registration.app.di; + +import dagger.Module; +import dagger.android.ContributesAndroidInjector; +import io.mosip.registration.app.MainActivity; + +@Module +public abstract class ActivityBuildersModule { + + @ContributesAndroidInjector + abstract MainActivity contributeMainActivity(); +} diff --git a/client/app/src/main/java/io/mosip/registration/app/di/AppComponent.java b/client/app/src/main/java/io/mosip/registration/app/di/AppComponent.java new file mode 100644 index 000000000..415768476 --- /dev/null +++ b/client/app/src/main/java/io/mosip/registration/app/di/AppComponent.java @@ -0,0 +1,29 @@ +package io.mosip.registration.app.di; + +import android.app.Application; + +import dagger.BindsInstance; +import dagger.Component; +import dagger.android.AndroidInjector; +import dagger.android.support.AndroidSupportInjectionModule; +import io.mosip.registration.app.BaseApplication; +import io.mosip.registration.clientmanager.service.crypto.LocalClientCryptoServiceImpl; + +@Component( + modules = { + AndroidSupportInjectionModule.class, + ActivityBuildersModule.class, + AppModule.class, + } +) +public interface AppComponent extends AndroidInjector { + + @Component.Builder + interface Builder{ + @BindsInstance + Builder application(Application application); + Builder appModule(AppModule appModule); + AppComponent build(); + } + +} diff --git a/client/app/src/main/java/io/mosip/registration/app/di/AppModule.java b/client/app/src/main/java/io/mosip/registration/app/di/AppModule.java new file mode 100644 index 000000000..f25159c06 --- /dev/null +++ b/client/app/src/main/java/io/mosip/registration/app/di/AppModule.java @@ -0,0 +1,40 @@ +package io.mosip.registration.app.di; + +import android.app.Application; +import android.content.Context; + +import androidx.annotation.NonNull; + +import javax.inject.Singleton; + +import dagger.Module; +import dagger.Provides; +import io.mosip.registration.clientmanager.service.crypto.LocalClientCryptoServiceImpl; + +@Module +public class AppModule { + + Application application; + Context appContext; + + public AppModule(Application application) { + this.application = application; + this.appContext = application.getApplicationContext(); + } + + @Provides + Application providesApplication() { + return application; + } + + @Provides + @NonNull + public Context provideApplicationContext() { + return appContext; + } + + @Provides + public LocalClientCryptoServiceImpl provideLocalClientCryptoServiceImpl(){ + return new LocalClientCryptoServiceImpl(appContext); + } +} \ No newline at end of file diff --git a/client/app/src/main/java/io/mosip/registration/app/di/ClientManagerModule.java b/client/app/src/main/java/io/mosip/registration/app/di/ClientManagerModule.java new file mode 100644 index 000000000..c19286ede --- /dev/null +++ b/client/app/src/main/java/io/mosip/registration/app/di/ClientManagerModule.java @@ -0,0 +1,18 @@ +//package io.mosip.registration.app.di; +// +//import android.content.Context; +// +//import javax.inject.Inject; +// +//import dagger.Module; +//import dagger.Provides; +//import io.mosip.registration.clientmanager.service.crypto.LocalClientCryptoServiceImpl; +// +//@Module +//public class ClientManagerModule { +// @Provides +// static LocalClientCryptoServiceImpl provideLocalClientCryptoServiceImpl(){ +// return new LocalClientCryptoServiceImpl(); +// } +// +//} diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java index d91d616d3..1fbcb525c 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java @@ -69,9 +69,9 @@ import android.R; @Singleton -public class LocalClientCryptoServiceImpl extends Service implements ClientCryptoManagerService { +public class LocalClientCryptoServiceImpl implements ClientCryptoManagerService { private static final String TAG = LocalClientCryptoServiceImpl.class.getSimpleName(); - private static Context context; + private Context context; // encoder and decoder from java itself private static Encoder base64encoder; @@ -115,24 +115,19 @@ public class LocalClientCryptoServiceImpl extends Service implements ClientCrypt private static SecureRandom secureRandom = null; - - // implementing service...extending binder - public class ClientCryptoServiceBinder extends Binder { - public LocalClientCryptoServiceImpl getServiceInstance(){ - return LocalClientCryptoServiceImpl.this; - } - } - - //creating instance of binder to be passed to MainActivity - private IBinder mBinder=new ClientCryptoServiceBinder(); - @Inject - public LocalClientCryptoServiceImpl() { + public LocalClientCryptoServiceImpl(Context appContext) { Log.i(TAG, "LocalClientCryptoServiceImpl: Constructor call successful"); + try { + initLocalClientCryptoService(appContext); + } catch (Exception e) { + Log.e(TAG, "LocalClientCryptoServiceImpl: Failed Initialization", e); + } + } - public void initLocalClientCryptoService() { - context = getApplicationContext(); + public void initLocalClientCryptoService(Context appContext) { + this.context = appContext; initializeClientSecurity(); @@ -142,51 +137,6 @@ public void initLocalClientCryptoService() { Log.i(TAG, "initLocalClientCryptoService: Initialization call successful"); } - // ON BIND BINDER FOR MAIN CLASS HERE - @Nullable - @Override - public IBinder onBind(Intent intent) { - return mBinder; - } - - - // on start of service -// @Override -// public void onStart(Intent intent, int startId) { -// super.onStart(intent, startId); -// } - - // on start command -// @Override -// public int onStartCommand(Intent intent, int flags, int startId) { -// initializeClientSecurity(); -// -// stopSelf(); -// return START_STICKY; -// } - - // onDestroy service - @Override - public void onDestroy() { - super.onDestroy(); -// any object to be destroyed should be destroyed here - } - - - // UNBIND METHOD - @Override - public boolean onUnbind(Intent intent) { - return super.onUnbind(intent); - } - - // REBIND - public void onRebind(Intent intent) { - super.onRebind(intent); - } - - - - private void initializeClientSecurity() { Log.i(TAG, "LocalClientCryptoServiceImpl: Initializing"); CRYPTO_ASYMMETRIC_ALGORITHM = ConfigService.getProperty("mosip.kernel.crypto.asymmetric-algorithm-name",context); From c64c417459236ae73bee83d0296687c2aa2d462c Mon Sep 17 00:00:00 2001 From: EricJohnEastwood Date: Sun, 3 Oct 2021 19:47:42 +0530 Subject: [PATCH 23/27] Add Instrumented Test --- .../ExampleInstrumentedTest.java | 145 +++++++++++++++++- 1 file changed, 141 insertions(+), 4 deletions(-) diff --git a/client/clientmanager/src/androidTest/java/io/mosip/registration/clientmanager/ExampleInstrumentedTest.java b/client/clientmanager/src/androidTest/java/io/mosip/registration/clientmanager/ExampleInstrumentedTest.java index 704a88053..e2b4ae374 100644 --- a/client/clientmanager/src/androidTest/java/io/mosip/registration/clientmanager/ExampleInstrumentedTest.java +++ b/client/clientmanager/src/androidTest/java/io/mosip/registration/clientmanager/ExampleInstrumentedTest.java @@ -7,8 +7,30 @@ import org.junit.Test; import org.junit.runner.RunWith; + +import org.junit.Before; + + import static org.junit.Assert.*; + +import io.mosip.registration.clientmanager.service.crypto.LocalClientCryptoServiceImpl; + + +import android.util.Log; +import android.R; + +import io.mosip.registration.clientmanager.dto.crypto.CryptoRequestDto; +import io.mosip.registration.clientmanager.dto.crypto.CryptoResponseDto; +import io.mosip.registration.clientmanager.dto.crypto.PublicKeyRequestDto; +import io.mosip.registration.clientmanager.dto.crypto.PublicKeyResponseDto; +import io.mosip.registration.clientmanager.dto.crypto.SignRequestDto; +import io.mosip.registration.clientmanager.dto.crypto.SignResponseDto; +import io.mosip.registration.clientmanager.dto.crypto.SignVerifyRequestDto; +import io.mosip.registration.clientmanager.dto.crypto.SignVerifyResponseDto; +import io.mosip.registration.clientmanager.spi.crypto.ClientCryptoManagerService; +import io.mosip.registration.clientmanager.util.ConfigService; + /** * Instrumented test, which will execute on an Android device. * @@ -16,10 +38,125 @@ */ @RunWith(AndroidJUnit4.class) public class ExampleInstrumentedTest { - @Test - public void useAppContext() { - // Context of the app under test. + + private static LocalClientCryptoServiceImpl localClientCryptoService; + + // encryption and decryption keys + private static PublicKeyRequestDto publicKeyRequestDto_encdec; + private static PublicKeyResponseDto publicKeyResponseDto_encdec; + + // sign and verify keys + private static PublicKeyRequestDto publicKeyRequestDto_sign; + private static PublicKeyResponseDto publicKeyResponseDto_sign; + + // to do initializations + @Before + public void init(){ +// creating localclientcrypto object for testing Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); - assertEquals("io.mosip.registration.clientmanager.test", appContext.getPackageName()); + localClientCryptoService=new LocalClientCryptoServiceImpl(appContext); + localClientCryptoService.initLocalClientCryptoService(appContext); + +// creating keys for encryption and dcryption testing + publicKeyRequestDto_encdec= new PublicKeyRequestDto(); + publicKeyRequestDto_encdec.setServerProfile("endec"); + publicKeyResponseDto_encdec = localClientCryptoService.getPublicKey(publicKeyRequestDto_encdec); + +// creating keys for sign and verify + publicKeyRequestDto_sign= new PublicKeyRequestDto(); + publicKeyRequestDto_sign.setServerProfile("sign"); + publicKeyResponseDto_sign = localClientCryptoService.getPublicKey(publicKeyRequestDto_sign); + + } + + + @Test + public void LoadLocalServiceImplTest() { + assertNotNull(localClientCryptoService); + assertNotNull(publicKeyResponseDto_encdec); + assertNotNull(publicKeyResponseDto_sign); } + + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } + + + + @Test + public void getPublicKey_test(){ +// checking public key for valid types such as endec + PublicKeyRequestDto pub_RequestDto = new PublicKeyRequestDto(); + pub_RequestDto.setServerProfile("endec"); + PublicKeyResponseDto pub_ResponseDto = localClientCryptoService.getPublicKey(pub_RequestDto); + assertNotNull(pub_ResponseDto); + +// checking for sign + PublicKeyRequestDto pub_RequestDto_sign = new PublicKeyRequestDto(); + pub_RequestDto_sign.setServerProfile("sign"); + PublicKeyResponseDto pub_ResponseDto_sign = localClientCryptoService.getPublicKey(pub_RequestDto_sign); + assertNotNull(pub_ResponseDto_sign); + + // checking for random string + PublicKeyRequestDto pub_RequestDto_sign2 = new PublicKeyRequestDto(); + pub_RequestDto_sign2.setServerProfile("random"); + PublicKeyResponseDto pub_ResponseDto_sign2 = localClientCryptoService.getPublicKey(pub_RequestDto_sign2); + assertNull(pub_ResponseDto_sign2); + + } + + @Test + public void encryption_decryption_test(){ + +// TESTCASE 1 + + + String input_message="First Message _+& 9901234 "; +// encryption + CryptoRequestDto cryptoRequestDto = new CryptoRequestDto( + input_message, publicKeyResponseDto_encdec.getPublicKey()); + CryptoResponseDto cryptoResponseDto = localClientCryptoService.encrypt(cryptoRequestDto); +// decryption + cryptoRequestDto.setValue(cryptoResponseDto.getValue()); + cryptoResponseDto=localClientCryptoService.decrypt(cryptoRequestDto); + assertEquals(input_message,cryptoResponseDto.getValue()); + +// TESTCASE 2 (CHECKING AGAINST WRONG INPUT) + assertNotEquals("wrong message",cryptoResponseDto.getValue()); + + + +// TESTCASE 3(against null string) + cryptoRequestDto.setValue(""); + cryptoResponseDto=localClientCryptoService.encrypt(cryptoRequestDto); + cryptoRequestDto.setValue(cryptoResponseDto.getValue()); + cryptoResponseDto=localClientCryptoService.decrypt(cryptoRequestDto); + assertEquals("",cryptoResponseDto.getValue()); + + } + + @Test + public void sign_verify_test(){ + String signMessage = "messageInput 123"; + String signed_string; + + SignRequestDto signRequestDto = new SignRequestDto(signMessage); + SignResponseDto signResponseDto = localClientCryptoService.sign(signRequestDto); + signed_string=signResponseDto.getData(); +// signing + +// TESTCASE 1 :CHECKING WITH CORRECT MESSAGE + SignVerifyRequestDto signVerifyRequestDto=new SignVerifyRequestDto(signMessage, signed_string, publicKeyResponseDto_sign.getPublicKey()); + SignVerifyResponseDto signVerifyResponseDto=localClientCryptoService.verifySign(signVerifyRequestDto); + assertTrue(signVerifyResponseDto.isVerified()); + +// TESTCASE 2:WITH WRONG MESSAGE + SignVerifyRequestDto signVerifyRequestDto_2=new SignVerifyRequestDto("DUMMY", signed_string, publicKeyResponseDto_sign.getPublicKey()); + SignVerifyResponseDto signVerifyResponseDto_2=localClientCryptoService.verifySign(signVerifyRequestDto_2); + assertFalse(signVerifyResponseDto_2.isVerified()); + + + } + } \ No newline at end of file From fc25a03752ca775711e19b93ff11894b4a0f8afe Mon Sep 17 00:00:00 2001 From: EricJohnEastwood Date: Tue, 5 Oct 2021 16:00:13 +0530 Subject: [PATCH 24/27] Update PublicKeyRequestDto and Base64Enc/Dec --- .../java/io/mosip/registration/app/MainActivity.java | 6 +++--- .../clientmanager/ExampleInstrumentedTest.java | 10 +++++----- .../clientmanager/dto/crypto/PublicKeyRequestDto.java | 2 +- .../service/crypto/LocalClientCryptoServiceImpl.java | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/client/app/src/main/java/io/mosip/registration/app/MainActivity.java b/client/app/src/main/java/io/mosip/registration/app/MainActivity.java index 31eaa43bc..6c721ce52 100644 --- a/client/app/src/main/java/io/mosip/registration/app/MainActivity.java +++ b/client/app/src/main/java/io/mosip/registration/app/MainActivity.java @@ -61,7 +61,7 @@ public void test_encrypt(View view) { Log.i(TAG, "test_encrypt: Encrypting...." + endecMessage); // creating public key request PublicKeyRequestDto publicKeyRequestDto = new PublicKeyRequestDto(); - publicKeyRequestDto.setServerProfile("endec"); + publicKeyRequestDto.setAlias("endec"); PublicKeyResponseDto publicKeyResponseDto = localClientCryptoService.getPublicKey(publicKeyRequestDto); Log.i(TAG,"Got public key..creating cryptoRequest"); @@ -84,7 +84,7 @@ public void test_decrypt(View view) { try { Log.i(TAG, "test_decrypt: Decrypting...."); PublicKeyRequestDto publicKeyRequestDto = new PublicKeyRequestDto(); - publicKeyRequestDto.setServerProfile("endec"); + publicKeyRequestDto.setAlias("endec"); PublicKeyResponseDto publicKeyResponseDto = localClientCryptoService.getPublicKey(publicKeyRequestDto); CryptoRequestDto cryptoRequestDto = new CryptoRequestDto(encryption, publicKeyResponseDto.getPublicKey()); @@ -127,7 +127,7 @@ public void test_verify(View view){ try{ Log.i(TAG, "test_verify: SignVerifying...."); PublicKeyRequestDto publicKeyRequestDto = new PublicKeyRequestDto(); - publicKeyRequestDto.setServerProfile("sign"); + publicKeyRequestDto.setAlias("sign"); PublicKeyResponseDto publicKeyResponseDto = localClientCryptoService.getPublicKey(publicKeyRequestDto); Log.i(TAG, "test_verify: Got public key..verifying signed data"); diff --git a/client/clientmanager/src/androidTest/java/io/mosip/registration/clientmanager/ExampleInstrumentedTest.java b/client/clientmanager/src/androidTest/java/io/mosip/registration/clientmanager/ExampleInstrumentedTest.java index e2b4ae374..e4b637e09 100644 --- a/client/clientmanager/src/androidTest/java/io/mosip/registration/clientmanager/ExampleInstrumentedTest.java +++ b/client/clientmanager/src/androidTest/java/io/mosip/registration/clientmanager/ExampleInstrumentedTest.java @@ -59,12 +59,12 @@ public void init(){ // creating keys for encryption and dcryption testing publicKeyRequestDto_encdec= new PublicKeyRequestDto(); - publicKeyRequestDto_encdec.setServerProfile("endec"); + publicKeyRequestDto_encdec.setAlias("endec"); publicKeyResponseDto_encdec = localClientCryptoService.getPublicKey(publicKeyRequestDto_encdec); // creating keys for sign and verify publicKeyRequestDto_sign= new PublicKeyRequestDto(); - publicKeyRequestDto_sign.setServerProfile("sign"); + publicKeyRequestDto_sign.setAlias("sign"); publicKeyResponseDto_sign = localClientCryptoService.getPublicKey(publicKeyRequestDto_sign); } @@ -88,19 +88,19 @@ public void addition_isCorrect() { public void getPublicKey_test(){ // checking public key for valid types such as endec PublicKeyRequestDto pub_RequestDto = new PublicKeyRequestDto(); - pub_RequestDto.setServerProfile("endec"); + pub_RequestDto.setAlias("endec"); PublicKeyResponseDto pub_ResponseDto = localClientCryptoService.getPublicKey(pub_RequestDto); assertNotNull(pub_ResponseDto); // checking for sign PublicKeyRequestDto pub_RequestDto_sign = new PublicKeyRequestDto(); - pub_RequestDto_sign.setServerProfile("sign"); + pub_RequestDto_sign.setAlias("sign"); PublicKeyResponseDto pub_ResponseDto_sign = localClientCryptoService.getPublicKey(pub_RequestDto_sign); assertNotNull(pub_ResponseDto_sign); // checking for random string PublicKeyRequestDto pub_RequestDto_sign2 = new PublicKeyRequestDto(); - pub_RequestDto_sign2.setServerProfile("random"); + pub_RequestDto_sign2.setAlias("random"); PublicKeyResponseDto pub_ResponseDto_sign2 = localClientCryptoService.getPublicKey(pub_RequestDto_sign2); assertNull(pub_ResponseDto_sign2); diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/PublicKeyRequestDto.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/PublicKeyRequestDto.java index 7a4966fed..bcc9904ce 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/PublicKeyRequestDto.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/crypto/PublicKeyRequestDto.java @@ -11,5 +11,5 @@ @NoArgsConstructor public class PublicKeyRequestDto { @NotBlank(message = "Invalid Request") - String serverProfile; + String alias; } diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java index 1fbcb525c..b86896d4f 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java @@ -166,8 +166,8 @@ private void initializeClientSecurity() { KEYGEN_ASYMMETRIC_ALGO_SIGN_PAD = ConfigService.getProperty("mosip.kernel.crypto.sign-algorithm-padding-scheme",context); CERTIFICATE_SIGN_ALGORITHM = ConfigService.getProperty("mosip.kernel.certificate.sign.algorithm",context); - base64encoder = Base64.getEncoder(); - base64decoder = Base64.getDecoder(); + base64encoder = Base64.getUrlEncoder(); + base64decoder = Base64.getUrlDecoder(); } private void genSignKey() { @@ -355,7 +355,7 @@ public PublicKeyResponseDto getPublicKey(PublicKeyRequestDto publicKeyRequestDto PublicKeyResponseDto publicKeyResponseDto = new PublicKeyResponseDto(); try { - String keyRequest = publicKeyRequestDto.getServerProfile(); + String keyRequest = publicKeyRequestDto.getAlias(); Log.i(TAG, "getPublicKey: Public key accessed for " + keyRequest); if(keyRequest == "sign") { PublicKey publicKey = getSignPublicKey(); From f99e3e5390dd756bdd8a5f52ea2d1e9f482daef3 Mon Sep 17 00:00:00 2001 From: EricJohnEastwood Date: Tue, 5 Oct 2021 16:31:02 +0530 Subject: [PATCH 25/27] Update PublicKeyRequestDto and Base64Enc/Dec --- .../mosip/registration/app/MainActivity.java | 9 +- .../ExampleInstrumentedTest.java | 13 +-- .../constant/KeyManagerConstant.java | 14 +++ .../constant/KeyManagerErrorCode.java | 88 +++++++++++++++++++ .../crypto/LocalClientCryptoServiceImpl.java | 7 +- 5 files changed, 121 insertions(+), 10 deletions(-) create mode 100644 client/clientmanager/src/main/java/io/mosip/registration/clientmanager/constant/KeyManagerConstant.java create mode 100644 client/clientmanager/src/main/java/io/mosip/registration/clientmanager/constant/KeyManagerErrorCode.java diff --git a/client/app/src/main/java/io/mosip/registration/app/MainActivity.java b/client/app/src/main/java/io/mosip/registration/app/MainActivity.java index 6c721ce52..e9a1c1d9e 100644 --- a/client/app/src/main/java/io/mosip/registration/app/MainActivity.java +++ b/client/app/src/main/java/io/mosip/registration/app/MainActivity.java @@ -1,5 +1,8 @@ package io.mosip.registration.app; +import static io.mosip.registration.clientmanager.constant.KeyManagerConstant.KEY_ENDEC; +import static io.mosip.registration.clientmanager.constant.KeyManagerConstant.KEY_SIGN; + import dagger.android.support.DaggerAppCompatActivity; import io.mosip.registration.clientmanager.dto.crypto.*; import androidx.appcompat.app.AppCompatActivity; @@ -61,7 +64,7 @@ public void test_encrypt(View view) { Log.i(TAG, "test_encrypt: Encrypting...." + endecMessage); // creating public key request PublicKeyRequestDto publicKeyRequestDto = new PublicKeyRequestDto(); - publicKeyRequestDto.setAlias("endec"); + publicKeyRequestDto.setAlias(KEY_ENDEC); PublicKeyResponseDto publicKeyResponseDto = localClientCryptoService.getPublicKey(publicKeyRequestDto); Log.i(TAG,"Got public key..creating cryptoRequest"); @@ -84,7 +87,7 @@ public void test_decrypt(View view) { try { Log.i(TAG, "test_decrypt: Decrypting...."); PublicKeyRequestDto publicKeyRequestDto = new PublicKeyRequestDto(); - publicKeyRequestDto.setAlias("endec"); + publicKeyRequestDto.setAlias(KEY_ENDEC); PublicKeyResponseDto publicKeyResponseDto = localClientCryptoService.getPublicKey(publicKeyRequestDto); CryptoRequestDto cryptoRequestDto = new CryptoRequestDto(encryption, publicKeyResponseDto.getPublicKey()); @@ -127,7 +130,7 @@ public void test_verify(View view){ try{ Log.i(TAG, "test_verify: SignVerifying...."); PublicKeyRequestDto publicKeyRequestDto = new PublicKeyRequestDto(); - publicKeyRequestDto.setAlias("sign"); + publicKeyRequestDto.setAlias(KEY_SIGN); PublicKeyResponseDto publicKeyResponseDto = localClientCryptoService.getPublicKey(publicKeyRequestDto); Log.i(TAG, "test_verify: Got public key..verifying signed data"); diff --git a/client/clientmanager/src/androidTest/java/io/mosip/registration/clientmanager/ExampleInstrumentedTest.java b/client/clientmanager/src/androidTest/java/io/mosip/registration/clientmanager/ExampleInstrumentedTest.java index e4b637e09..43976f2d0 100644 --- a/client/clientmanager/src/androidTest/java/io/mosip/registration/clientmanager/ExampleInstrumentedTest.java +++ b/client/clientmanager/src/androidTest/java/io/mosip/registration/clientmanager/ExampleInstrumentedTest.java @@ -14,6 +14,9 @@ import static org.junit.Assert.*; +import static io.mosip.registration.clientmanager.constant.KeyManagerConstant.KEY_ENDEC; +import static io.mosip.registration.clientmanager.constant.KeyManagerConstant.KEY_SIGN; + import io.mosip.registration.clientmanager.service.crypto.LocalClientCryptoServiceImpl; @@ -57,14 +60,14 @@ public void init(){ localClientCryptoService=new LocalClientCryptoServiceImpl(appContext); localClientCryptoService.initLocalClientCryptoService(appContext); -// creating keys for encryption and dcryption testing +// creating keys for encryption and decryption testing publicKeyRequestDto_encdec= new PublicKeyRequestDto(); - publicKeyRequestDto_encdec.setAlias("endec"); + publicKeyRequestDto_encdec.setAlias(KEY_ENDEC); publicKeyResponseDto_encdec = localClientCryptoService.getPublicKey(publicKeyRequestDto_encdec); // creating keys for sign and verify publicKeyRequestDto_sign= new PublicKeyRequestDto(); - publicKeyRequestDto_sign.setAlias("sign"); + publicKeyRequestDto_sign.setAlias(KEY_SIGN); publicKeyResponseDto_sign = localClientCryptoService.getPublicKey(publicKeyRequestDto_sign); } @@ -88,13 +91,13 @@ public void addition_isCorrect() { public void getPublicKey_test(){ // checking public key for valid types such as endec PublicKeyRequestDto pub_RequestDto = new PublicKeyRequestDto(); - pub_RequestDto.setAlias("endec"); + pub_RequestDto.setAlias(KEY_ENDEC); PublicKeyResponseDto pub_ResponseDto = localClientCryptoService.getPublicKey(pub_RequestDto); assertNotNull(pub_ResponseDto); // checking for sign PublicKeyRequestDto pub_RequestDto_sign = new PublicKeyRequestDto(); - pub_RequestDto_sign.setAlias("sign"); + pub_RequestDto_sign.setAlias(KEY_SIGN); PublicKeyResponseDto pub_ResponseDto_sign = localClientCryptoService.getPublicKey(pub_RequestDto_sign); assertNotNull(pub_ResponseDto_sign); diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/constant/KeyManagerConstant.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/constant/KeyManagerConstant.java new file mode 100644 index 000000000..0d7884b0e --- /dev/null +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/constant/KeyManagerConstant.java @@ -0,0 +1,14 @@ +package io.mosip.registration.clientmanager.constant; + +public class KeyManagerConstant { + private KeyManagerConstant() { + + } + public static final String WHITESPACE = " "; + public static final String INVALID_REQUEST = "should not be null or empty"; + public static final String EMPTY_ATTRIBUTE = "should not be empty"; + public static final String EMPTY_REGEX = ".+\\S.*"; + + public static final String KEY_ENDEC = "ENDEC"; + public static final String KEY_SIGN = "SIGN"; +} \ No newline at end of file diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/constant/KeyManagerErrorCode.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/constant/KeyManagerErrorCode.java new file mode 100644 index 000000000..8e8093cc8 --- /dev/null +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/constant/KeyManagerErrorCode.java @@ -0,0 +1,88 @@ +package io.mosip.registration.clientmanager.constant; + +public enum KeyManagerErrorCode { + /** + * + */ + NO_SUCH_ALGORITHM_EXCEPTION("KER-CRY-001", "No Such algorithm is supported"), + /** + * + */ + INVALID_SPEC_PUBLIC_KEY("KER-CRY-002", "public key is invalid"), + /** + * + */ + INVALID_DATA_WITHOUT_KEY_BREAKER("KER-CRY-003", "data sent to decrypt is without key splitter or invalid"), + /** + * + */ + INVALID_DATA("KER-CRY-003", " or not base64 encoded"), + /** + * + */ + INVALID_REQUEST("KER-CRY-004", "should not be null or empty"), + /** + * + */ + CANNOT_CONNECT_TO_KEYMANAGER_SERVICE("KER-CRY-005", "cannot connect to keymanager service or response is null"), + /** + * + */ + KEYMANAGER_SERVICE_ERROR("KER-CRY-006", "Keymanager Service has replied with following error"), + /** + * + */ + RESPONSE_PARSE_ERROR("KER-CRY-008", "Error occur while parsing response "), + /** + * + */ + DATE_TIME_PARSE_EXCEPTION("KER-CRY-007", "timestamp should be in ISO 8601 format yyyy-MM-ddTHH::mm:ss.SZ"), + /** + * + */ + HEX_DATA_PARSE_EXCEPTION("KER-CRY-009", "Invalid Hex Data"), + + CERTIFICATE_THUMBPRINT_ERROR("KER-CRY-010", "Error in generating Certificate Thumbprint."), + + ENCRYPT_NOT_ALLOWED_ERROR("KER-CRY-011", "Not Allowed to preform encryption with Master Key. Use Base to encrypt data."), + + INTERNAL_SERVER_ERROR("KER-CRY-500", "Internal server error"); + + /** + * The errorCode + */ + private final String errorCode; + /** + * The errorMessage + */ + private final String errorMessage; + + /** + * {@link KeyManagerErrorCode} constructor + * + * @param errorCode error code + * @param errorMessage error message + */ + private KeyManagerErrorCode(final String errorCode, final String errorMessage) { + this.errorCode = errorCode; + this.errorMessage = errorMessage; + } + + /** + * Getter for errorCode + * + * @return errorCode + */ + public String getErrorCode() { + return errorCode; + } + + /** + * Getter for errorMessage + * + * @return errorMessage + */ + public String getErrorMessage() { + return errorMessage; + } +} diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java index b86896d4f..5d4d38bcb 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java @@ -1,5 +1,8 @@ package io.mosip.registration.clientmanager.service.crypto; +import static io.mosip.registration.clientmanager.constant.KeyManagerConstant.KEY_ENDEC; +import static io.mosip.registration.clientmanager.constant.KeyManagerConstant.KEY_SIGN; + import android.app.Service; import android.content.Context; import android.content.Intent; @@ -357,14 +360,14 @@ public PublicKeyResponseDto getPublicKey(PublicKeyRequestDto publicKeyRequestDto try { String keyRequest = publicKeyRequestDto.getAlias(); Log.i(TAG, "getPublicKey: Public key accessed for " + keyRequest); - if(keyRequest == "sign") { + if(keyRequest == KEY_SIGN) { PublicKey publicKey = getSignPublicKey(); Log.i(TAG, "getPublicKey: Sign Public key accessed "); String public_key = base64encoder.encodeToString(publicKey.getEncoded()); publicKeyResponseDto.setPublicKey(public_key); return publicKeyResponseDto; } - else if(keyRequest == "endec") { + else if(keyRequest == KEY_ENDEC) { PublicKey publicKey = getEnDecPublicKey(); Log.i(TAG, "getPublicKey: EnDec Public key accessed "); String public_key = base64encoder.encodeToString(publicKey.getEncoded()); From 067e651512d78c26bc5573c74cb64067d30068df Mon Sep 17 00:00:00 2001 From: EricJohnEastwood Date: Wed, 6 Oct 2021 15:09:33 +0530 Subject: [PATCH 26/27] Add deatiled exceptions --- .../crypto/LocalClientCryptoServiceImpl.java | 125 ++++++++++++++++-- 1 file changed, 111 insertions(+), 14 deletions(-) diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java index 5d4d38bcb..d0831dd37 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java @@ -30,12 +30,15 @@ import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Signature; +import java.security.SignatureException; import java.security.UnrecoverableEntryException; import java.security.cert.CertificateException; +import java.security.spec.InvalidKeySpecException; import java.security.spec.MGF1ParameterSpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; @@ -173,6 +176,7 @@ private void initializeClientSecurity() { base64decoder = Base64.getUrlDecoder(); } + // done with errors private void genSignKey() { try { KeyPairGenerator kpg = KeyPairGenerator.getInstance( @@ -191,11 +195,22 @@ private void genSignKey() { Log.i(TAG, "genSignKey: Generated signing private key successfully " + base64encoder.encodeToString(kp.getPublic().getEncoded())); - } catch(Exception e) { + } + catch(NoSuchAlgorithmException e) { + Log.e(TAG, "genSignKey: Sign key generation failed ", e); + } + catch(NoSuchProviderException e) { + Log.e(TAG, "genSignKey: Sign key generation failed ", e); + } + catch(IllegalArgumentException e) { + Log.e(TAG, "genSignKey: Sign key generation failed ", e); + } + catch(InvalidAlgorithmParameterException e) { Log.e(TAG, "genSignKey: Sign key generation failed ", e); } } + // done with error private void genEnDecKey() { try { KeyPairGenerator kpg = KeyPairGenerator.getInstance( @@ -203,7 +218,7 @@ private void genEnDecKey() { final KeyGenParameterSpec keyPairGenParameterSpec = new KeyGenParameterSpec.Builder( ENDEC_ALIAS, - KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) + KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) .setBlockModes(KEYGEN_ASYMMETRIC_ALGO_BLOCK) .setKeySize(KEYGEN_ASYMMETRIC_KEY_LENGTH) .setEncryptionPaddings(KEYGEN_ASYMMETRIC_ALGO_PAD) @@ -215,11 +230,22 @@ private void genEnDecKey() { Log.i(TAG, "genEnDecKey: Generated encryption private key successfully " + base64encoder.encodeToString(kp.getPublic().getEncoded())); - } catch(Exception e) { - Log.e(TAG, "genEnDecKey: Encryption key generation failed ", e); + } catch(NoSuchAlgorithmException e) { + Log.e(TAG, "genSignKey: Sign key generation failed ", e); + } + catch(NoSuchProviderException e) { + Log.e(TAG, "genSignKey: Sign key generation failed ", e); + } + catch(IllegalArgumentException e) { + Log.e(TAG, "genSignKey: Sign key generation failed ", e); + } + catch(InvalidAlgorithmParameterException e) { + Log.e(TAG, "genSignKey: Sign key generation failed ", e); } } + + // done @Override public SignResponseDto sign(SignRequestDto signRequestDto) { SignResponseDto signResponseDto = new SignResponseDto(); @@ -235,12 +261,32 @@ public SignResponseDto sign(SignRequestDto signRequestDto) { signResponseDto.setData(base64encoder.encodeToString(signedData)); return signResponseDto; - } catch (Exception e) { + } + catch (KeyStoreException e) { + Log.e(TAG, "sign: Signing Failed ", e); + } + catch (CertificateException e) { + Log.e(TAG, "sign: Signing Failed ", e); + } + catch (NoSuchAlgorithmException e) { + Log.e(TAG, "sign: Signing Failed ", e); + } + catch (IOException e) { + Log.e(TAG, "sign: Signing Failed ", e); + } + catch (UnrecoverableEntryException e) { Log.e(TAG, "sign: Signing Failed ", e); } + catch (SignatureException e) { + e.printStackTrace(); + } catch (InvalidKeyException e) { + e.printStackTrace(); + } + return null; } + // done @Override public SignVerifyResponseDto verifySign(SignVerifyRequestDto signVerifyRequestDto) { SignVerifyResponseDto signVerifyResponseDto = new SignVerifyResponseDto(); @@ -261,13 +307,20 @@ public SignVerifyResponseDto verifySign(SignVerifyRequestDto signVerifyRequestDt signVerifyResponseDto.setVerified(result); return signVerifyResponseDto; + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (SignatureException e) { + e.printStackTrace(); + } catch (InvalidKeyException e) { + e.printStackTrace(); + } catch (InvalidKeySpecException e) { + e.printStackTrace(); } - catch(Exception e) { - Log.e(TAG, "verifySign: Sign Verification Failed", e); - } + return null; } + // done @Override public CryptoResponseDto encrypt(CryptoRequestDto cryptoRequestDto) { CryptoResponseDto cryptoResponseDto = new CryptoResponseDto(); @@ -310,13 +363,29 @@ public CryptoResponseDto encrypt(CryptoRequestDto cryptoRequestDto) { cryptoResponseDto.setValue(base64encoder.encodeToString(encrypted_key_iv_data)); return cryptoResponseDto; - } catch(Exception e) { - Log.e(TAG, "encrypt: Encryption failed ", e); + } catch (InvalidKeySpecException e) { + e.printStackTrace(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (BadPaddingException e) { + e.printStackTrace(); + } catch (InvalidKeyException e) { + e.printStackTrace(); + } catch (InvalidAlgorithmParameterException e) { + e.printStackTrace(); + } catch (NoSuchPaddingException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (IllegalBlockSizeException e) { + e.printStackTrace(); } + return null; } + // done @Override public CryptoResponseDto decrypt(CryptoRequestDto cryptoRequestDto) { CryptoResponseDto cryptoResponseDto = new CryptoResponseDto(); @@ -347,9 +416,29 @@ public CryptoResponseDto decrypt(CryptoRequestDto cryptoRequestDto) { String decodedString = new String(decodedBytes); cryptoResponseDto.setValue(decodedString); return cryptoResponseDto; - } catch(Exception e) { - Log.e(TAG, "decrypt: Decryption failed", e); } + catch (InvalidKeyException e) { + e.printStackTrace(); + } catch (UnrecoverableEntryException e) { + e.printStackTrace(); + } catch (KeyStoreException e) { + e.printStackTrace(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (CertificateException e) { + e.printStackTrace(); + } catch (InvalidAlgorithmParameterException e) { + e.printStackTrace(); + } catch (IllegalBlockSizeException e) { + e.printStackTrace(); + } catch (BadPaddingException e) { + e.printStackTrace(); + } catch (NoSuchPaddingException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return null; } @@ -374,8 +463,16 @@ else if(keyRequest == KEY_ENDEC) { publicKeyResponseDto.setPublicKey(public_key); return publicKeyResponseDto; } - } catch(Exception e) { - Log.e(TAG, "getPublicKey: Public key access failed ", e); + } catch (IOException e) { + e.printStackTrace(); + } catch (CertificateException e) { + e.printStackTrace(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (UnrecoverableEntryException e) { + e.printStackTrace(); + } catch (KeyStoreException e) { + e.printStackTrace(); } return null; } From 869e72eb573208012bc9baa13f47cfe666018ee1 Mon Sep 17 00:00:00 2001 From: EricJohnEastwood Date: Sat, 9 Oct 2021 21:41:33 +0530 Subject: [PATCH 27/27] Add KeyManagerErrorCode --- .../constant/KeyManagerErrorCode.java | 27 ++++ .../crypto/LocalClientCryptoServiceImpl.java | 132 +++++++++--------- 2 files changed, 92 insertions(+), 67 deletions(-) diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/constant/KeyManagerErrorCode.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/constant/KeyManagerErrorCode.java index 8e8093cc8..bd7564ac6 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/constant/KeyManagerErrorCode.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/constant/KeyManagerErrorCode.java @@ -46,8 +46,35 @@ public enum KeyManagerErrorCode { ENCRYPT_NOT_ALLOWED_ERROR("KER-CRY-011", "Not Allowed to preform encryption with Master Key. Use Base to encrypt data."), +//NEWLY ADDED ERROR CODES + + NO_SUCH_PROVIDER_EXCEPTION("KER-CRY-012","Specified provider is not registered in the security provider list"), + + INVALID_ALGORITHM_PARAMETER_EXCEPTION("KER-CRY-013","Invalid ALgorithm Parameter provided for function call"), + + ILLEGAL_ARGUMENT_EXCEPTION("KER-CRY-013","Illegal argument provided to function(NULL or EMPTY)"), + + KEY_STORE_EXCEPTION("KER-CRY-014","implementation for the specified type is not available from the specified provider"), + + CERTIFICATE_EXCEPTION("KER-CRY-015","Some of the certificates included in the keystore data could not be stored"), + + IO_EXCEPTION("KER-CRY-016","There was an I/O problem with data"), + + UNRECOVERABLE_ENTRY_EXCEPTION("KER-CRY-017","the specified protection Parameter for Keystore were insufficient or invalid"), + + SIGNATURE_EXCEPTION("KER-CRY-018","Signature object not initialized properly / signature algorithm unable to process input data"), + + INVALID_KEY_EXCEPTION("KER-CRY-019","Provided Key is Invalid"), + + BAD_PADDING_EXCEPTION("KER-CRY-020","The decrypted data is not bounded by the appropriate padding bytes"), + + NO_SUCH_PADDING_EXCEPTION("KER-CRY-021","Padding scheme is not available"), + + ILLEGAL_BLOCKSIZE_EXCEPTION("KER-CRY-022"," Input Data length processed by cipher is not multiple of block size"), + INTERNAL_SERVER_ERROR("KER-CRY-500", "Internal server error"); + /** * The errorCode */ diff --git a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java index d0831dd37..6718f0e11 100644 --- a/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java +++ b/client/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/crypto/LocalClientCryptoServiceImpl.java @@ -3,25 +3,12 @@ import static io.mosip.registration.clientmanager.constant.KeyManagerConstant.KEY_ENDEC; import static io.mosip.registration.clientmanager.constant.KeyManagerConstant.KEY_SIGN; -import android.app.Service; + import android.content.Context; -import android.content.Intent; -import android.os.Binder; -import android.os.IBinder; import android.security.keystore.KeyGenParameterSpec; import android.security.keystore.KeyProperties; - -import androidx.annotation.Nullable; - import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.OutputStreamWriter; -import java.nio.file.AccessDeniedException; -import java.nio.file.Files; -import java.nio.file.Paths; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.KeyFactory; @@ -40,13 +27,11 @@ import java.security.cert.CertificateException; import java.security.spec.InvalidKeySpecException; import java.security.spec.MGF1ParameterSpec; -import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Arrays; import java.util.Base64; import java.util.Base64.Decoder; import java.util.Base64.Encoder; -import java.util.Objects; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; @@ -72,7 +57,7 @@ import io.mosip.registration.clientmanager.spi.crypto.ClientCryptoManagerService; import io.mosip.registration.clientmanager.util.ConfigService; import android.util.Log; -import android.R; +import io.mosip.registration.clientmanager.constant.*; @Singleton public class LocalClientCryptoServiceImpl implements ClientCryptoManagerService { @@ -176,7 +161,7 @@ private void initializeClientSecurity() { base64decoder = Base64.getUrlDecoder(); } - // done with errors + // done with errors completely private void genSignKey() { try { KeyPairGenerator kpg = KeyPairGenerator.getInstance( @@ -197,20 +182,23 @@ private void genSignKey() { } catch(NoSuchAlgorithmException e) { - Log.e(TAG, "genSignKey: Sign key generation failed ", e); + Log.e(TAG, KeyManagerErrorCode.NO_SUCH_ALGORITHM_EXCEPTION.getErrorMessage(), e); } catch(NoSuchProviderException e) { - Log.e(TAG, "genSignKey: Sign key generation failed ", e); + Log.e(TAG,KeyManagerErrorCode.NO_SUCH_PROVIDER_EXCEPTION.getErrorMessage(), e); } catch(IllegalArgumentException e) { - Log.e(TAG, "genSignKey: Sign key generation failed ", e); + Log.e(TAG,KeyManagerErrorCode.ILLEGAL_ARGUMENT_EXCEPTION.getErrorMessage(), e); } catch(InvalidAlgorithmParameterException e) { + Log.e(TAG, KeyManagerErrorCode.INVALID_ALGORITHM_PARAMETER_EXCEPTION.getErrorMessage(), e); + } + catch(Exception e){ Log.e(TAG, "genSignKey: Sign key generation failed ", e); } } - // done with error + // done with error completely private void genEnDecKey() { try { KeyPairGenerator kpg = KeyPairGenerator.getInstance( @@ -230,22 +218,27 @@ private void genEnDecKey() { Log.i(TAG, "genEnDecKey: Generated encryption private key successfully " + base64encoder.encodeToString(kp.getPublic().getEncoded())); - } catch(NoSuchAlgorithmException e) { - Log.e(TAG, "genSignKey: Sign key generation failed ", e); + } + catch(NoSuchAlgorithmException e) { + Log.e(TAG, KeyManagerErrorCode.NO_SUCH_ALGORITHM_EXCEPTION.getErrorMessage(), e); } catch(NoSuchProviderException e) { - Log.e(TAG, "genSignKey: Sign key generation failed ", e); + Log.e(TAG,KeyManagerErrorCode.NO_SUCH_PROVIDER_EXCEPTION.getErrorMessage(), e); } catch(IllegalArgumentException e) { - Log.e(TAG, "genSignKey: Sign key generation failed ", e); + Log.e(TAG,KeyManagerErrorCode.ILLEGAL_ARGUMENT_EXCEPTION.getErrorMessage(), e); } catch(InvalidAlgorithmParameterException e) { + Log.e(TAG, KeyManagerErrorCode.INVALID_ALGORITHM_PARAMETER_EXCEPTION.getErrorMessage(), e); + } + catch(Exception e){ Log.e(TAG, "genSignKey: Sign key generation failed ", e); } + } - // done + // done with error completely @Override public SignResponseDto sign(SignRequestDto signRequestDto) { SignResponseDto signResponseDto = new SignResponseDto(); @@ -263,30 +256,31 @@ public SignResponseDto sign(SignRequestDto signRequestDto) { } catch (KeyStoreException e) { - Log.e(TAG, "sign: Signing Failed ", e); + Log.e(TAG, KeyManagerErrorCode.KEY_STORE_EXCEPTION.getErrorMessage(), e); } catch (CertificateException e) { - Log.e(TAG, "sign: Signing Failed ", e); + Log.e(TAG, KeyManagerErrorCode.CERTIFICATE_EXCEPTION.getErrorMessage(), e); } catch (NoSuchAlgorithmException e) { - Log.e(TAG, "sign: Signing Failed ", e); + Log.e(TAG, KeyManagerErrorCode.NO_SUCH_ALGORITHM_EXCEPTION.getErrorMessage(), e); } catch (IOException e) { - Log.e(TAG, "sign: Signing Failed ", e); + Log.e(TAG, KeyManagerErrorCode.IO_EXCEPTION.getErrorMessage(), e); } catch (UnrecoverableEntryException e) { - Log.e(TAG, "sign: Signing Failed ", e); + Log.e(TAG, KeyManagerErrorCode.UNRECOVERABLE_ENTRY_EXCEPTION.getErrorMessage(), e); } catch (SignatureException e) { - e.printStackTrace(); - } catch (InvalidKeyException e) { - e.printStackTrace(); + Log.e(TAG, KeyManagerErrorCode.SIGNATURE_EXCEPTION.getErrorMessage(), e); + } + catch (InvalidKeyException e) { + Log.e(TAG, KeyManagerErrorCode.INVALID_KEY_EXCEPTION.getErrorMessage(), e); } return null; } - // done + // done with error completely @Override public SignVerifyResponseDto verifySign(SignVerifyRequestDto signVerifyRequestDto) { SignVerifyResponseDto signVerifyResponseDto = new SignVerifyResponseDto(); @@ -308,13 +302,13 @@ public SignVerifyResponseDto verifySign(SignVerifyRequestDto signVerifyRequestDt signVerifyResponseDto.setVerified(result); return signVerifyResponseDto; } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); + Log.e(TAG, KeyManagerErrorCode.NO_SUCH_ALGORITHM_EXCEPTION.getErrorMessage(), e); } catch (SignatureException e) { - e.printStackTrace(); + Log.e(TAG, KeyManagerErrorCode.SIGNATURE_EXCEPTION.getErrorMessage(), e); } catch (InvalidKeyException e) { - e.printStackTrace(); + Log.e(TAG, KeyManagerErrorCode.INVALID_KEY_EXCEPTION.getErrorMessage(), e); } catch (InvalidKeySpecException e) { - e.printStackTrace(); + Log.e(TAG, KeyManagerErrorCode.INVALID_SPEC_PUBLIC_KEY.getErrorMessage(), e); } return null; @@ -364,28 +358,31 @@ public CryptoResponseDto encrypt(CryptoRequestDto cryptoRequestDto) { cryptoResponseDto.setValue(base64encoder.encodeToString(encrypted_key_iv_data)); return cryptoResponseDto; } catch (InvalidKeySpecException e) { - e.printStackTrace(); + Log.e(TAG, KeyManagerErrorCode.INVALID_SPEC_PUBLIC_KEY.getErrorMessage(), e); } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - } catch (BadPaddingException e) { - e.printStackTrace(); - } catch (InvalidKeyException e) { - e.printStackTrace(); + Log.e(TAG, KeyManagerErrorCode.NO_SUCH_ALGORITHM_EXCEPTION.getErrorMessage(), e); + } + catch (BadPaddingException e) { + Log.e(TAG, KeyManagerErrorCode.BAD_PADDING_EXCEPTION.getErrorMessage(), e); + } + catch (InvalidKeyException e) { + Log.e(TAG, KeyManagerErrorCode.INVALID_KEY_EXCEPTION.getErrorMessage(), e); } catch (InvalidAlgorithmParameterException e) { - e.printStackTrace(); + Log.e(TAG, KeyManagerErrorCode.INVALID_ALGORITHM_PARAMETER_EXCEPTION.getErrorMessage(), e); } catch (NoSuchPaddingException e) { - e.printStackTrace(); + Log.e(TAG, KeyManagerErrorCode.NO_SUCH_PADDING_EXCEPTION.getErrorMessage(), e); } catch (IOException e) { - e.printStackTrace(); - } catch (IllegalBlockSizeException e) { - e.printStackTrace(); + Log.e(TAG, KeyManagerErrorCode.IO_EXCEPTION.getErrorMessage(), e); + } + catch (IllegalBlockSizeException e) { + Log.e(TAG, KeyManagerErrorCode.ILLEGAL_BLOCKSIZE_EXCEPTION.getErrorMessage(), e); } return null; } - // done + // done completely with errors @Override public CryptoResponseDto decrypt(CryptoRequestDto cryptoRequestDto) { CryptoResponseDto cryptoResponseDto = new CryptoResponseDto(); @@ -418,30 +415,31 @@ public CryptoResponseDto decrypt(CryptoRequestDto cryptoRequestDto) { return cryptoResponseDto; } catch (InvalidKeyException e) { - e.printStackTrace(); + Log.e(TAG, KeyManagerErrorCode.INVALID_KEY_EXCEPTION.getErrorMessage(), e); } catch (UnrecoverableEntryException e) { - e.printStackTrace(); + Log.e(TAG, KeyManagerErrorCode.UNRECOVERABLE_ENTRY_EXCEPTION.getErrorMessage(), e); } catch (KeyStoreException e) { - e.printStackTrace(); + Log.e(TAG, KeyManagerErrorCode.KEY_STORE_EXCEPTION.getErrorMessage(), e); } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); + Log.e(TAG, KeyManagerErrorCode.NO_SUCH_ALGORITHM_EXCEPTION.getErrorMessage(), e); } catch (CertificateException e) { - e.printStackTrace(); + Log.e(TAG, KeyManagerErrorCode.CERTIFICATE_EXCEPTION.getErrorMessage(), e); } catch (InvalidAlgorithmParameterException e) { - e.printStackTrace(); + Log.e(TAG, KeyManagerErrorCode.INVALID_ALGORITHM_PARAMETER_EXCEPTION.getErrorMessage(), e); } catch (IllegalBlockSizeException e) { - e.printStackTrace(); + Log.e(TAG, KeyManagerErrorCode.ILLEGAL_BLOCKSIZE_EXCEPTION.getErrorMessage(), e); } catch (BadPaddingException e) { - e.printStackTrace(); + Log.e(TAG, KeyManagerErrorCode.BAD_PADDING_EXCEPTION.getErrorMessage(), e); } catch (NoSuchPaddingException e) { - e.printStackTrace(); + Log.e(TAG, KeyManagerErrorCode.NO_SUCH_PADDING_EXCEPTION.getErrorMessage(), e); } catch (IOException e) { - e.printStackTrace(); + Log.e(TAG, KeyManagerErrorCode.IO_EXCEPTION.getErrorMessage(), e); } return null; } + // done completely with errors @Override public PublicKeyResponseDto getPublicKey(PublicKeyRequestDto publicKeyRequestDto) { PublicKeyResponseDto publicKeyResponseDto = new PublicKeyResponseDto(); @@ -464,15 +462,15 @@ else if(keyRequest == KEY_ENDEC) { return publicKeyResponseDto; } } catch (IOException e) { - e.printStackTrace(); + Log.e(TAG, KeyManagerErrorCode.IO_EXCEPTION.getErrorMessage(), e); } catch (CertificateException e) { - e.printStackTrace(); + Log.e(TAG, KeyManagerErrorCode.CERTIFICATE_EXCEPTION.getErrorMessage(), e); } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); + Log.e(TAG, KeyManagerErrorCode.NO_SUCH_ALGORITHM_EXCEPTION.getErrorMessage(), e); } catch (UnrecoverableEntryException e) { - e.printStackTrace(); + Log.e(TAG, KeyManagerErrorCode.UNRECOVERABLE_ENTRY_EXCEPTION.getErrorMessage(), e); } catch (KeyStoreException e) { - e.printStackTrace(); + Log.e(TAG, KeyManagerErrorCode.KEY_STORE_EXCEPTION.getErrorMessage(), e); } return null; }