-
Notifications
You must be signed in to change notification settings - Fork 104
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Loading status checks…
MOSIP-34075 removed secret keys
Signed-off-by: Sohan Kumar Dey <[email protected]>
Showing
33 changed files
with
2,866 additions
and
444 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
apitest-commons/src/main/java/io/mosip/testrig/apirig/admin/fw/config/BeanConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package io.mosip.testrig.apirig.admin.fw.config; | ||
|
||
import org.springframework.context.annotation.ComponentScan; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.context.annotation.Import; | ||
|
||
import io.mosip.kernel.crypto.jce.core.CryptoCore; | ||
|
||
@Configuration | ||
@Import({ CryptoCore.class }) | ||
@ComponentScan(basePackages = { "io.mosip.testrig.apirig", "io.mosip.testrig.dslrig"}) | ||
public class BeanConfig { | ||
int i = 0; | ||
} |
12 changes: 12 additions & 0 deletions
12
apitest-commons/src/main/java/io/mosip/testrig/apirig/dto/EncryptionRequestDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package io.mosip.testrig.apirig.dto; | ||
|
||
import lombok.Data; | ||
|
||
import java.util.Map; | ||
|
||
@Data | ||
public class EncryptionRequestDto { | ||
|
||
private Map<String, Object> identityRequest; | ||
|
||
} |
10 changes: 10 additions & 0 deletions
10
apitest-commons/src/main/java/io/mosip/testrig/apirig/dto/EncryptionResponseDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package io.mosip.testrig.apirig.dto; | ||
|
||
import lombok.Data; | ||
|
||
@Data | ||
public class EncryptionResponseDto { | ||
String encryptedSessionKey; | ||
String encryptedIdentity; | ||
String requestHMAC; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
275 changes: 275 additions & 0 deletions
275
apitest-commons/src/main/java/io/mosip/testrig/apirig/utils/AuthUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,275 @@ | ||
package io.mosip.testrig.apirig.utils; | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
|
||
import io.mosip.authentication.core.constant.IdAuthenticationErrorConstants; | ||
import io.mosip.authentication.core.exception.IdAuthenticationAppException; | ||
import io.mosip.authentication.core.exception.IdAuthenticationBusinessException; | ||
import io.mosip.authentication.core.indauth.dto.IdType; | ||
import io.mosip.authentication.core.spi.indauth.match.MatchType; | ||
import io.mosip.kernel.core.exception.ExceptionUtils; | ||
import io.mosip.kernel.core.exception.ServiceError; | ||
import io.mosip.kernel.core.templatemanager.spi.TemplateManager; | ||
import io.mosip.kernel.core.util.CryptoUtil; | ||
import io.mosip.kernel.core.util.DateUtils; | ||
import io.mosip.testrig.apirig.dto.CertificateChainResponseDto; | ||
|
||
import org.apache.commons.codec.digest.DigestUtils; | ||
import org.apache.commons.io.IOUtils; | ||
import org.bouncycastle.operator.OperatorCreationException; | ||
import org.jose4j.lang.JoseException; | ||
import org.json.JSONException; | ||
import org.springframework.lang.Nullable; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RequestParam; | ||
|
||
|
||
import javax.crypto.BadPaddingException; | ||
import javax.crypto.IllegalBlockSizeException; | ||
import javax.crypto.NoSuchPaddingException; | ||
import javax.xml.bind.DatatypeConverter; | ||
import java.io.*; | ||
import java.net.URI; | ||
import java.net.http.HttpResponse; | ||
import java.nio.charset.StandardCharsets; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.nio.file.Paths; | ||
import java.security.*; | ||
import java.security.cert.Certificate; | ||
import java.security.cert.CertificateEncodingException; | ||
import java.security.cert.CertificateException; | ||
import java.security.cert.X509Certificate; | ||
import java.security.spec.InvalidKeySpecException; | ||
import java.util.*; | ||
import java.util.function.BiFunction; | ||
import java.util.stream.Stream; | ||
|
||
public class AuthUtil { | ||
|
||
public AuthUtil() { | ||
mapper = new ObjectMapper(); | ||
} | ||
|
||
private ObjectMapper mapper; | ||
private static final String PIN = "pin"; | ||
|
||
private static final String BIO = "bio"; | ||
|
||
private static final String DEMO = "demo"; | ||
|
||
private static final String OTP = "otp"; | ||
private static final String BEGIN_CERTIFICATE = "-----BEGIN CERTIFICATE-----"; | ||
private static final String END_CERTIFICATE = "-----END CERTIFICATE-----"; | ||
|
||
private static final String LINE_SEPARATOR = System.getProperty("line.separator"); | ||
|
||
private static final String TIMESTAMP = "timestamp"; | ||
|
||
private static final String ID = "id"; | ||
|
||
private static final String AUTH_TYPE = "authType"; | ||
|
||
private static final String SECONDARY_LANG_CODE = "secondaryLangCode"; | ||
|
||
private static final String TXN = "txn"; | ||
|
||
private static final String VER = "ver"; | ||
|
||
private static final String ENV = "env"; | ||
|
||
private static final String DOMAIN_URI = "domainUri"; | ||
|
||
private static final String IDA_API_VERSION = "ida.api.version"; | ||
|
||
private static final String MOSIP_ENV = "Staging"; | ||
|
||
private static final String MOSIP_DOMAINURI = "mosip.base.url"; | ||
public static final String BIOMETRICS = "biometrics"; | ||
|
||
private static final String IDA_AUTH_REQUEST_TEMPLATE = "ida.authRequest.template"; | ||
|
||
private static final String DATE_TIME = "dateTime"; | ||
|
||
private static final String TRANSACTION_ID = "transactionId"; | ||
|
||
private static final String IDENTITY = "Identity"; | ||
|
||
private static final String TEMPLATE = "Template"; | ||
|
||
|
||
public void clearKeys(String certsDir, String moduleName, String targetEnv) throws IOException { | ||
KeyMgrUtility keyMgrUtil = new KeyMgrUtility(); | ||
keyMgrUtil.deleteFile(new File(keyMgrUtil.getKeysDirPath(certsDir, moduleName, targetEnv).toString())); | ||
} | ||
|
||
public CertificateChainResponseDto generatePartnerKeys( | ||
PartnerTypes partnerType, String partnerName, boolean keyFileNameByPartnerName, String certsDir, String moduleName, String targetEnv) throws UnrecoverableEntryException, CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException, OperatorCreationException { | ||
KeyMgrUtility keyMgrUtil = new KeyMgrUtility(); | ||
return keyMgrUtil.getPartnerCertificates(partnerType, keyMgrUtil.getKeysDirPath(certsDir, moduleName, targetEnv), partnerName, | ||
keyFileNameByPartnerName); | ||
} | ||
|
||
public String updatePartnerCertificate( | ||
PartnerTypes partnerType, String partnerName, boolean keyFileNameByPartnerName, Map<String, String> requestData, String certsDir, | ||
String moduleName, String targetEnv) throws CertificateException, | ||
IOException, NoSuchAlgorithmException, UnrecoverableEntryException, KeyStoreException { | ||
KeyMgrUtility keyMgrUtil = new KeyMgrUtility(); | ||
String certificateData = requestData.get("certData"); | ||
String filePrepend = partnerType.getFilePrepend(); | ||
|
||
X509Certificate x509Cert = (X509Certificate) keyMgrUtil.convertToCertificate(certificateData); | ||
System.out.println("certificateType: " + partnerType.toString()); | ||
System.out.println("filePrepend: " + filePrepend); | ||
boolean isUpdated = keyMgrUtil.updatePartnerCertificate(filePrepend, x509Cert, keyMgrUtil.getKeysDirPath(certsDir, moduleName, targetEnv), | ||
partnerName, keyFileNameByPartnerName); | ||
return isUpdated ? "Update Success" : "Update Failed"; | ||
} | ||
|
||
public String uploadIDACertificate( | ||
CertificateTypes certificateType, | ||
Map<String, String> requestData, | ||
String certsDir, | ||
String moduleName, | ||
String targetEnv) | ||
throws CertificateException, IOException { | ||
KeyMgrUtility keyMgrUtil = new KeyMgrUtility(); | ||
|
||
String certificateData = requestData.get("certData"); | ||
String fileName = certificateType.getFileName(); | ||
System.out.println("certificateType: " + certificateType.toString()); | ||
System.out.println("FileName: " + fileName); | ||
|
||
X509Certificate x509Cert = (X509Certificate) keyMgrUtil.convertToCertificate(certificateData); | ||
Base64.Encoder base64Encoder = Base64.getMimeEncoder(64, LINE_SEPARATOR.getBytes()); | ||
byte[] certificateBytes = x509Cert.getEncoded(); | ||
String encodedCertificateData = new String(base64Encoder.encode(certificateBytes)); | ||
StringBuilder strBuilder = new StringBuilder(); | ||
strBuilder.append(BEGIN_CERTIFICATE); | ||
strBuilder.append(LINE_SEPARATOR); | ||
strBuilder.append(encodedCertificateData); | ||
strBuilder.append(LINE_SEPARATOR); | ||
strBuilder.append(END_CERTIFICATE); | ||
String certificateStr = strBuilder.toString(); | ||
|
||
String keysDirPath = keyMgrUtil.getKeysDirPath(certsDir, moduleName, targetEnv); | ||
|
||
Path parentPath = Paths.get(keysDirPath + "/" + fileName).getParent(); | ||
if (parentPath != null && !Files.exists(parentPath)) { | ||
Files.createDirectories(parentPath); | ||
} | ||
|
||
boolean isErrored = false; | ||
try (BufferedWriter writer = new BufferedWriter(new FileWriter(keysDirPath + "/" + fileName))) { | ||
writer.write(certificateStr); | ||
writer.flush(); | ||
} catch (Exception e) { | ||
System.err.println(e.getMessage()); | ||
isErrored = true; | ||
} | ||
|
||
return isErrored ? "Upload Failed" : "Upload Success"; | ||
} | ||
|
||
private String digest(byte[] hash) throws NoSuchAlgorithmException { | ||
return DatatypeConverter.printHexBinary(hash).toUpperCase(); | ||
} | ||
|
||
public byte[] getCertificateThumbprint(Certificate cert) throws CertificateEncodingException { | ||
return DigestUtils.sha256(cert.getEncoded()); | ||
} | ||
|
||
// private void idValuesMap(String id, boolean isKyc, boolean isInternal, Map<String, Object> reqValues, | ||
// String transactionId, String utcCurrentDateTimeString) { | ||
// reqValues.put(ID, id); | ||
// if (isInternal) { | ||
// reqValues.put(AUTH_TYPE, "auth.internal"); | ||
// } else { | ||
// if (isKyc) { | ||
// reqValues.put(AUTH_TYPE, "kyc"); | ||
// reqValues.put(SECONDARY_LANG_CODE, PropertiesReader.readProperty("mosip.secondary-language")); | ||
// } else { | ||
// reqValues.put(AUTH_TYPE, "auth"); | ||
// } | ||
// } | ||
// | ||
// reqValues.put(TIMESTAMP, utcCurrentDateTimeString); | ||
// reqValues.put(TXN, transactionId == null ? "1234567890" : transactionId); | ||
// reqValues.put(VER, PropertiesReader.readProperty(IDA_API_VERSION)); | ||
// reqValues.put(DOMAIN_URI, PropertiesReader.readProperty(MOSIP_DOMAINURI)); | ||
// reqValues.put(ENV, MOSIP_ENV); | ||
// } | ||
|
||
private void getAuthTypeMap(String reqAuth, Map<String, Object> reqValues, Map<String, Object> request) { | ||
String[] reqAuthArr; | ||
if (reqAuth == null) { | ||
BiFunction<String, String, Optional<String>> authTypeMapFunction = (key, authType) -> Optional | ||
.ofNullable(request).filter(map -> map.containsKey(key)).map(map -> authType); | ||
reqAuthArr = Stream | ||
.of(authTypeMapFunction.apply("demographics", "demo"), authTypeMapFunction.apply(BIOMETRICS, "bio"), | ||
authTypeMapFunction.apply("otp", "otp"), authTypeMapFunction.apply("staticPin", "pin")) | ||
.filter(Optional::isPresent).map(Optional::get).toArray(size -> new String[size]); | ||
} else { | ||
reqAuth = reqAuth.trim(); | ||
if (reqAuth.contains(",")) { | ||
reqAuthArr = reqAuth.split(","); | ||
} else { | ||
reqAuthArr = new String[]{reqAuth}; | ||
} | ||
} | ||
|
||
for (String authType : reqAuthArr) { | ||
authTypeSelectionMap(reqValues, authType); | ||
} | ||
} | ||
|
||
private void authTypeSelectionMap(Map<String, Object> reqValues, String authType) { | ||
|
||
if (authType.equalsIgnoreCase(MatchType.Category.OTP.getType())) { | ||
reqValues.put(OTP, true); | ||
} else if (authType.equalsIgnoreCase(MatchType.Category.DEMO.getType())) { | ||
reqValues.put(DEMO, true); | ||
} else if (authType.equalsIgnoreCase(MatchType.Category.BIO.getType())) { | ||
reqValues.put(BIO, true); | ||
} else if (authType.equalsIgnoreCase(MatchType.Category.SPIN.getType())) { | ||
reqValues.put("pin", true); | ||
} | ||
} | ||
|
||
private void applyRecursively(Object obj, String key, String value) { | ||
if (obj instanceof Map) { | ||
Map<String, Object> map = (Map<String, Object>) obj; | ||
Optional<String> matchingKey = map.keySet().stream().filter(k -> k.equalsIgnoreCase(key)).findFirst(); | ||
if (matchingKey.isPresent()) { | ||
map.put(matchingKey.get(), value); | ||
} | ||
|
||
for (Object val : map.values()) { | ||
applyRecursively(val, key, value); | ||
} | ||
} else if (obj instanceof List) { | ||
List<?> list = (List<?>) obj; | ||
for (Object object : list) { | ||
applyRecursively(object, key, value); | ||
} | ||
} | ||
} | ||
|
||
public String signRequest( | ||
PartnerTypes partnerType, | ||
String partnerName, | ||
boolean keyFileNameByPartnerName, | ||
String request, | ||
String certsDir, | ||
String moduleName, | ||
String targetEnv) | ||
throws JoseException, NoSuchAlgorithmException, UnrecoverableEntryException, KeyStoreException, | ||
CertificateException, IOException, OperatorCreationException { | ||
KeyMgrUtility keyMgrUtil = new KeyMgrUtility(); | ||
JWSSignAndVerifyController jWSSignAndVerifyController = new JWSSignAndVerifyController(); | ||
return jWSSignAndVerifyController.sign(request, false, | ||
true, false, null, keyMgrUtil.getKeysDirPath(certsDir, moduleName, targetEnv), partnerType, partnerName, keyFileNameByPartnerName); | ||
} | ||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
apitest-commons/src/main/java/io/mosip/testrig/apirig/utils/CertificateChainResponseDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package io.mosip.testrig.apirig.utils; | ||
|
||
import lombok.Data; | ||
|
||
@Data | ||
public class CertificateChainResponseDto { | ||
|
||
String caCertificate; | ||
|
||
String interCertificate; | ||
|
||
String partnerCertificate; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 18 additions & 0 deletions
18
apitest-commons/src/main/java/io/mosip/testrig/apirig/utils/CertificateTypes.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package io.mosip.testrig.apirig.utils; | ||
|
||
public enum CertificateTypes { | ||
|
||
INTERNAL("ida-internal.cer"), | ||
PARTNER("ida-partner.cer"), | ||
IDA_FIR("ida-fir.cer"); | ||
|
||
private String fileName; | ||
|
||
private CertificateTypes(String fileName) { | ||
this.fileName = fileName; | ||
} | ||
|
||
public String getFileName() { | ||
return this.fileName; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
353 changes: 353 additions & 0 deletions
353
apitest-commons/src/main/java/io/mosip/testrig/apirig/utils/CryptoCoreUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,353 @@ | ||
package io.mosip.testrig.apirig.utils; | ||
|
||
import io.mosip.kernel.core.crypto.exception.InvalidParamSpecException; | ||
import io.mosip.kernel.core.util.CryptoUtil; | ||
import io.mosip.kernel.crypto.jce.constant.SecurityExceptionCodeConstant; | ||
import io.mosip.kernel.crypto.jce.util.CryptoUtils; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.apache.commons.codec.digest.DigestUtils; | ||
import org.bouncycastle.crypto.InvalidCipherTextException; | ||
import org.bouncycastle.crypto.digests.SHA256Digest; | ||
import org.bouncycastle.crypto.encodings.OAEPEncoding; | ||
import org.bouncycastle.crypto.engines.RSAEngine; | ||
import org.bouncycastle.crypto.params.RSAKeyParameters; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.stereotype.Component; | ||
|
||
import javax.crypto.*; | ||
import javax.crypto.spec.GCMParameterSpec; | ||
import javax.crypto.spec.OAEPParameterSpec; | ||
import javax.crypto.spec.PSource.PSpecified; | ||
import javax.crypto.spec.SecretKeySpec; | ||
import java.math.BigInteger; | ||
import java.security.*; | ||
import java.security.KeyStore.PrivateKeyEntry; | ||
import java.security.cert.Certificate; | ||
import java.security.interfaces.RSAPrivateKey; | ||
import java.security.spec.MGF1ParameterSpec; | ||
import java.util.Arrays; | ||
import java.util.Objects; | ||
|
||
import static java.util.Arrays.copyOfRange; | ||
|
||
@Slf4j | ||
@Component | ||
public class CryptoCoreUtil { | ||
|
||
private final static String RSA_ECB_OAEP_PADDING = "RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING"; | ||
|
||
private final static int THUMBPRINT_LENGTH = 32; | ||
private final static int NONCE = 12; | ||
private final static int AADSize = 32; | ||
public static final byte[] VERSION_RSA_2048 = "VER_R2".getBytes(); | ||
|
||
private static final String MGF1 = "MGF1"; | ||
|
||
private static final String HASH_ALGO = "SHA-256"; | ||
|
||
private static final String PKCS11_STORE_TYPE = "PKCS11"; | ||
|
||
// Used as a hack for softhsm oeap padding decryption usecase will be when we | ||
// will use in HSM | ||
@SuppressWarnings("java:S106") | ||
private static final String RSA_ECB_NO_PADDING = "RSA/ECB/NoPadding"; // NOSONAR using the padding for allowing OAEP padding in PKCS11 library | ||
|
||
|
||
@Value("${mosip.prependThumbprint:true}") | ||
private boolean isThumbprint; | ||
|
||
@Value("${mosip.kernel.crypto.asymmetric-algorithm-name:" + RSA_ECB_OAEP_PADDING + "}") | ||
private String asymmetricAlgorithm; | ||
|
||
@Value("${mosip.kernel.keymanager.hsm.keystore-type:PKCS11}") | ||
private String keystoreType; | ||
|
||
@Value("${mosip.kernel.keygenerator.asymmetric-key-length:2048}") | ||
private int asymmetricKeyLength; | ||
|
||
|
||
public String decrypt(String data, PrivateKeyEntry privateKeyEntry) throws Exception { | ||
try { | ||
byte[] dataBytes = CryptoUtil.decodeURLSafeBase64(data); | ||
byte[] decryptedDataBytes = decryptData(dataBytes, privateKeyEntry); | ||
return new String(decryptedDataBytes); | ||
}catch (Exception e){ | ||
log.error( "Not able to decrypt the data : {}", e); | ||
} | ||
throw new Exception("Unknown decryption exception."); | ||
} | ||
|
||
public byte[] decryptData(byte[] requestData, PrivateKeyEntry privateKey) throws Exception { | ||
String keySplitter = "#KEY_SPLITTER#"; | ||
SecretKey symmetricKey = null; | ||
byte[] encryptedData = null; | ||
byte[] encryptedSymmetricKey = null; | ||
final int cipherKeyandDataLength = requestData.length; | ||
final int keySplitterLength = keySplitter.length(); | ||
|
||
int keyDemiliterIndex = getSplitterIndex(requestData, 0, keySplitter); | ||
byte[] encryptedKey = copyOfRange(requestData, 0, keyDemiliterIndex); | ||
byte[] headerBytes = parseEncryptKeyHeader(encryptedKey); | ||
byte[] decryptedSymmetricKey = null; | ||
try { | ||
encryptedData = copyOfRange(requestData, keyDemiliterIndex + keySplitterLength, cipherKeyandDataLength); | ||
if (Arrays.equals(headerBytes, VERSION_RSA_2048)) { | ||
encryptedSymmetricKey = Arrays.copyOfRange(encryptedKey, THUMBPRINT_LENGTH + VERSION_RSA_2048.length, | ||
encryptedKey.length); | ||
byte[] aad = Arrays.copyOfRange(encryptedData, 0, AADSize); | ||
byte[] nonce = Arrays.copyOfRange(aad, 0, NONCE); | ||
byte[] encData = Arrays.copyOfRange(encryptedData, AADSize, encryptedData.length); | ||
decryptedSymmetricKey = asymmetricDecrypt(privateKey.getPrivateKey(), | ||
((RSAPrivateKey) privateKey.getPrivateKey()).getModulus(), encryptedSymmetricKey); | ||
symmetricKey = new SecretKeySpec(decryptedSymmetricKey, 0, decryptedSymmetricKey.length, "AES"); | ||
return symmetricDecrypt(symmetricKey, encData, nonce, aad); | ||
} else if (isThumbprint) { | ||
encryptedSymmetricKey = Arrays.copyOfRange(encryptedKey, THUMBPRINT_LENGTH, encryptedKey.length); | ||
decryptedSymmetricKey = asymmetricDecrypt(privateKey.getPrivateKey(), | ||
((RSAPrivateKey) privateKey.getPrivateKey()).getModulus(), encryptedSymmetricKey); | ||
symmetricKey = new SecretKeySpec(decryptedSymmetricKey, 0, decryptedSymmetricKey.length, "AES"); | ||
return symmetricDecrypt(symmetricKey, encryptedData, null); | ||
} else { | ||
decryptedSymmetricKey = asymmetricDecrypt(privateKey.getPrivateKey(), | ||
((RSAPrivateKey) privateKey.getPrivateKey()).getModulus(), encryptedKey); | ||
symmetricKey = new SecretKeySpec(decryptedSymmetricKey, 0, decryptedSymmetricKey.length, "AES"); | ||
return symmetricDecrypt(symmetricKey, encryptedData, null); | ||
} | ||
} catch (Exception e) { | ||
log.error( "Not able to decrypt the data : {}", e); | ||
} | ||
throw new Exception("Unknown decryption exception."); | ||
} | ||
|
||
public byte[] parseEncryptKeyHeader(byte[] encryptedKey) { | ||
byte[] versionHeaderBytes = Arrays.copyOfRange(encryptedKey, 0, VERSION_RSA_2048.length); | ||
if (!Arrays.equals(versionHeaderBytes, VERSION_RSA_2048)) { | ||
return new byte[0]; | ||
} | ||
return versionHeaderBytes; | ||
} | ||
|
||
private static int getSplitterIndex(byte[] encryptedData, int keyDemiliterIndex, String keySplitter) { | ||
final byte keySplitterFirstByte = keySplitter.getBytes()[0]; | ||
final int keySplitterLength = keySplitter.length(); | ||
for (byte data : encryptedData) { | ||
if (data == keySplitterFirstByte) { | ||
final String keySplit = new String( | ||
copyOfRange(encryptedData, keyDemiliterIndex, keyDemiliterIndex + keySplitterLength)); | ||
if (keySplitter.equals(keySplit)) { | ||
break; | ||
} | ||
} | ||
keyDemiliterIndex++; | ||
} | ||
return keyDemiliterIndex; | ||
} | ||
|
||
/** | ||
* | ||
* @param privateKey | ||
* @param keyModulus | ||
* @param data | ||
* @return | ||
* @throws IllegalBlockSizeException | ||
* @throws BadPaddingException | ||
* @throws NoSuchAlgorithmException | ||
* @throws NoSuchPaddingException | ||
* @throws InvalidAlgorithmParameterException | ||
* @throws InvalidKeyException | ||
*/ | ||
private static byte[] asymmetricDecrypt(PrivateKey privateKey, BigInteger keyModulus, byte[] data) | ||
throws IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, | ||
InvalidAlgorithmParameterException, InvalidKeyException { | ||
|
||
Cipher cipher; | ||
try { | ||
cipher = Cipher.getInstance(RSA_ECB_OAEP_PADDING); | ||
OAEPParameterSpec oaepParams = new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, | ||
PSpecified.DEFAULT); | ||
cipher.init(Cipher.DECRYPT_MODE, privateKey, oaepParams); | ||
return cipher.doFinal(data); | ||
} catch (NoSuchAlgorithmException e) { | ||
log.error("Not able to decrypt the data : {}" , e); | ||
throw new NoSuchAlgorithmException(e); | ||
} catch (NoSuchPaddingException e) { | ||
throw new NoSuchPaddingException(e.getMessage()); | ||
} catch (InvalidKeyException e) { | ||
throw new InvalidKeyException(e); | ||
} catch (InvalidAlgorithmParameterException e) { | ||
throw new InvalidAlgorithmParameterException(e); | ||
} | ||
} | ||
|
||
private static byte[] symmetricDecrypt(SecretKey key, byte[] data, byte[] aad) { | ||
byte[] output = null; | ||
try { | ||
Cipher cipher = Cipher.getInstance("AES/GCM/PKCS5Padding"); | ||
byte[] randomIV = Arrays.copyOfRange(data, data.length - cipher.getBlockSize(), data.length); | ||
SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "AES"); | ||
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, randomIV); | ||
|
||
cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec); | ||
if (aad != null && aad.length != 0) { | ||
cipher.updateAAD(aad); | ||
} | ||
output = cipher.doFinal(Arrays.copyOf(data, data.length - cipher.getBlockSize())); | ||
} catch (Exception e) { | ||
|
||
} | ||
return output; | ||
} | ||
|
||
public byte[] symmetricDecrypt(SecretKey key, byte[] data, byte[] nonce, byte[] aad) | ||
throws Exception { | ||
// Objects.requireNonNull(key, null); | ||
// CryptoUtils.verifyData(data); | ||
byte[] output = null; | ||
Cipher cipher; | ||
try { | ||
cipher = Cipher.getInstance("AES/GCM/PKCS5Padding"); | ||
SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "AES"); | ||
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, nonce); | ||
cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec); | ||
if (aad != null) { | ||
cipher.updateAAD(aad); | ||
} | ||
output = cipher.doFinal(data, 0, data.length); | ||
} catch (InvalidAlgorithmParameterException e) { | ||
throw new Exception("Invalid key exception.", e); | ||
} catch (IllegalBlockSizeException e) { | ||
throw new Exception("Invalid key exception.", e); | ||
} catch (BadPaddingException e) { | ||
throw new Exception("Certificate thumbprint error.", e); | ||
} catch (NoSuchAlgorithmException e) { | ||
throw new Exception("Certificate thumbprint error.", e); | ||
} catch (NoSuchPaddingException e) { | ||
throw new Exception("Certificate thumbprint error.", e); | ||
} catch (InvalidKeyException e) { | ||
throw new Exception("Invalid key exception.", e); | ||
} | ||
return output; | ||
} | ||
|
||
public static byte[] getCertificateThumbprint(Certificate cert) throws Exception { | ||
try { | ||
return DigestUtils.sha256(cert.getEncoded()); | ||
} catch (java.security.cert.CertificateEncodingException e) { | ||
throw new Exception("Invalid key exception.", e); | ||
} | ||
} | ||
|
||
public byte[] asymmetricEncrypt(PublicKey key, byte[] data) throws GeneralSecurityException { | ||
Objects.requireNonNull(key, SecurityExceptionCodeConstant.MOSIP_INVALID_KEY_EXCEPTION.getErrorMessage()); | ||
CryptoUtils.verifyData(data); | ||
Cipher cipher; | ||
try { | ||
cipher = Cipher.getInstance(asymmetricAlgorithm); | ||
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) { | ||
throw e; | ||
} | ||
final OAEPParameterSpec oaepParams = new OAEPParameterSpec(HASH_ALGO, MGF1, MGF1ParameterSpec.SHA256, | ||
PSpecified.DEFAULT); | ||
try { | ||
cipher.init(Cipher.ENCRYPT_MODE, key, oaepParams); | ||
} catch (InvalidKeyException e) { | ||
throw e; | ||
} catch (InvalidAlgorithmParameterException e) { | ||
throw new InvalidParamSpecException( | ||
SecurityExceptionCodeConstant.MOSIP_INVALID_PARAM_SPEC_EXCEPTION.getErrorCode(), | ||
SecurityExceptionCodeConstant.MOSIP_INVALID_PARAM_SPEC_EXCEPTION.getErrorMessage(), e); | ||
} | ||
return doFinal(data, cipher); | ||
} | ||
|
||
public byte[] asymmetricDecrypt(PrivateKey privateKey, byte[] data) throws GeneralSecurityException, InvalidCipherTextException { | ||
if (PKCS11_STORE_TYPE.equalsIgnoreCase(keystoreType)) { | ||
BigInteger keyModulus = ((RSAPrivateKey) privateKey).getModulus(); | ||
return asymmetricDecrypt(privateKey, keyModulus, data, null); | ||
} | ||
return jceAsymmetricDecrypt(privateKey, data, null); | ||
} | ||
|
||
private byte[] asymmetricDecrypt(PrivateKey privateKey, BigInteger keyModulus, byte[] data, String storeType) throws GeneralSecurityException, InvalidCipherTextException { | ||
Objects.requireNonNull(privateKey, SecurityExceptionCodeConstant.MOSIP_INVALID_KEY_EXCEPTION.getErrorMessage()); | ||
CryptoUtils.verifyData(data); | ||
Cipher cipher; | ||
try { | ||
cipher = Objects.isNull(storeType) ? Cipher.getInstance(RSA_ECB_NO_PADDING) : // NOSONAR using the padding for allowing OAEP padding in PKCS11 library | ||
Cipher.getInstance(RSA_ECB_NO_PADDING, storeType); // NOSONAR using the padding for allowing OAEP padding in PKCS11 library | ||
} catch (NoSuchAlgorithmException | NoSuchPaddingException | NoSuchProviderException e) { | ||
throw e; | ||
} | ||
|
||
try { | ||
cipher.init(Cipher.DECRYPT_MODE, privateKey); | ||
} catch (InvalidKeyException e) { | ||
throw e; | ||
} | ||
/* | ||
* This is a hack of removing OEAP padding after decryption with NO Padding as | ||
* SoftHSM does not support it.Will be removed after HSM implementation | ||
*/ | ||
byte[] paddedPlainText = doFinal(data, cipher); | ||
if (paddedPlainText.length < asymmetricKeyLength / 8) { | ||
byte[] tempPipe = new byte[asymmetricKeyLength / 8]; | ||
System.arraycopy(paddedPlainText, 0, tempPipe, tempPipe.length - paddedPlainText.length, | ||
paddedPlainText.length); | ||
paddedPlainText = tempPipe; | ||
} | ||
|
||
return unpadOAEPPadding(paddedPlainText, keyModulus); | ||
} | ||
|
||
// This is a hack of removing OEAP padding after decryption with NO Padding as | ||
// SoftHSM does not support it.Will be removed after HSM implementation | ||
/** | ||
* | ||
* @param paddedPlainText | ||
* @param privateKey | ||
* @return | ||
* @throws InvalidCipherTextException | ||
*/ | ||
private byte[] unpadOAEPPadding(byte[] paddedPlainText, BigInteger keyModulus) throws InvalidCipherTextException { | ||
|
||
try { | ||
OAEPEncoding encode = new OAEPEncoding(new RSAEngine(), new SHA256Digest()); | ||
BigInteger exponent = new BigInteger("1"); | ||
RSAKeyParameters keyParams = new RSAKeyParameters(false, keyModulus, exponent); | ||
encode.init(false, keyParams); | ||
return encode.processBlock(paddedPlainText, 0, paddedPlainText.length); | ||
} catch (InvalidCipherTextException e) { | ||
throw e; | ||
} | ||
} | ||
|
||
private byte[] jceAsymmetricDecrypt(PrivateKey privateKey, byte[] data, String storeType) throws GeneralSecurityException{ | ||
Objects.requireNonNull(privateKey, SecurityExceptionCodeConstant.MOSIP_INVALID_KEY_EXCEPTION.getErrorMessage()); | ||
CryptoUtils.verifyData(data); | ||
Cipher cipher; | ||
try { | ||
cipher = Objects.isNull(storeType) ? Cipher.getInstance(asymmetricAlgorithm) : | ||
Cipher.getInstance(asymmetricAlgorithm, storeType); | ||
OAEPParameterSpec oaepParams = new OAEPParameterSpec(HASH_ALGO, MGF1, MGF1ParameterSpec.SHA256, | ||
PSpecified.DEFAULT); | ||
cipher.init(Cipher.DECRYPT_MODE, privateKey, oaepParams); | ||
return doFinal(data, cipher); | ||
} catch (NoSuchAlgorithmException | NoSuchPaddingException | NoSuchProviderException e) { | ||
throw e; | ||
} catch (InvalidKeyException e) { | ||
throw e; | ||
} catch (InvalidAlgorithmParameterException e) { | ||
throw e; | ||
} | ||
} | ||
|
||
private byte[] doFinal(byte[] data, Cipher cipher) throws IllegalBlockSizeException, BadPaddingException { | ||
try { | ||
return cipher.doFinal(data); | ||
} catch (IllegalBlockSizeException e) { | ||
throw e; | ||
} catch (BadPaddingException e) { | ||
throw e; | ||
} | ||
} | ||
} |
131 changes: 131 additions & 0 deletions
131
apitest-commons/src/main/java/io/mosip/testrig/apirig/utils/CryptoUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
package io.mosip.testrig.apirig.utils; | ||
|
||
import io.mosip.kernel.core.crypto.spi.CryptoCoreSpec; | ||
import org.bouncycastle.jce.provider.BouncyCastleProvider; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.stereotype.Component; | ||
|
||
import javax.crypto.*; | ||
import java.security.*; | ||
|
||
|
||
/** | ||
* The Class CryptoUtility is used for encryption and decryption. | ||
* | ||
* @author Arun Bose S | ||
* The Class CryptoUtil. | ||
*/ | ||
@Component | ||
public class CryptoUtil { | ||
|
||
/** The Constant SYM_ALGORITHM. */ | ||
private static final String SYM_ALGORITHM = "AES"; | ||
|
||
/** The Constant SYM_ALGORITHM_LENGTH. */ | ||
private static final int SYM_ALGORITHM_LENGTH = 256; | ||
|
||
/** The bouncy castle provider. */ | ||
private static BouncyCastleProvider bouncyCastleProvider; | ||
|
||
static { | ||
bouncyCastleProvider = addProvider(); | ||
} | ||
|
||
/** | ||
* {@link CryptoCoreSpec} instance for cryptographic functionalities. | ||
*/ | ||
@Autowired | ||
private CryptoCoreSpec<byte[], byte[], SecretKey, PublicKey, PrivateKey, String> cryptoCore; | ||
|
||
|
||
|
||
/** | ||
* Symmetric encrypt. | ||
* | ||
* @param data the data | ||
* @param secretKey the secret key | ||
* @return the byte[] | ||
* @throws NoSuchAlgorithmException the no such algorithm exception | ||
* @throws NoSuchPaddingException the no such padding exception | ||
* @throws InvalidKeyException the invalid key exception | ||
* @throws InvalidAlgorithmParameterException the invalid algorithm parameter exception | ||
* @throws IllegalBlockSizeException the illegal block size exception | ||
* @throws BadPaddingException the bad padding exception | ||
*/ | ||
public byte[] symmetricEncrypt(byte[] data, SecretKey secretKey) | ||
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, | ||
InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException { | ||
return cryptoCore.symmetricEncrypt(secretKey, data, null); | ||
|
||
} | ||
|
||
|
||
|
||
/** | ||
* Symmetric decrypt. | ||
* | ||
* @param secretKey the secret key | ||
* @param encryptedDataByteArr the encrypted data byte arr | ||
* @return the byte[] | ||
* @throws NoSuchAlgorithmException the no such algorithm exception | ||
* @throws NoSuchPaddingException the no such padding exception | ||
* @throws InvalidKeyException the invalid key exception | ||
* @throws IllegalBlockSizeException the illegal block size exception | ||
* @throws BadPaddingException the bad padding exception | ||
* @throws InvalidAlgorithmParameterException the invalid algorithm parameter exception | ||
*/ | ||
public byte[] symmetricDecrypt(SecretKey secretKey, byte[] encryptedDataByteArr) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException { | ||
return cryptoCore.symmetricDecrypt(secretKey, encryptedDataByteArr, null); | ||
} | ||
|
||
/** | ||
* Adds the provider. | ||
* | ||
* @return the bouncy castle provider | ||
*/ | ||
private static BouncyCastleProvider addProvider() { | ||
BouncyCastleProvider bouncyCastleProvider = new BouncyCastleProvider(); | ||
Security.addProvider(bouncyCastleProvider); | ||
return bouncyCastleProvider; | ||
} | ||
|
||
/** | ||
* Gen sec key. | ||
* | ||
* @return the secret key | ||
* @throws NoSuchAlgorithmException the no such algorithm exception | ||
*/ | ||
public SecretKey genSecKey() throws NoSuchAlgorithmException { | ||
KeyGenerator keyGen; | ||
SecretKey secretKey = null; | ||
keyGen = KeyGenerator.getInstance(CryptoUtil.SYM_ALGORITHM, bouncyCastleProvider); | ||
keyGen.init(CryptoUtil.SYM_ALGORITHM_LENGTH, new SecureRandom()); | ||
secretKey = keyGen.generateKey(); | ||
return secretKey; | ||
|
||
} | ||
|
||
/** | ||
* Asymmetric encrypt. | ||
* | ||
* @param data the data | ||
* @param publicKey the public key | ||
* @return the byte[] | ||
* @throws NoSuchAlgorithmException the no such algorithm exception | ||
* @throws NoSuchPaddingException the no such padding exception | ||
* @throws InvalidKeyException the invalid key exception | ||
* @throws IllegalBlockSizeException the illegal block size exception | ||
* @throws BadPaddingException the bad padding exception | ||
*/ | ||
public byte[] asymmetricEncrypt(byte[] data, PublicKey publicKey) throws NoSuchAlgorithmException, | ||
NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { | ||
return cryptoCore.asymmetricEncrypt(publicKey, data); | ||
} | ||
|
||
public byte[] symmetricEncrypt(byte[] data, SecretKey secretKey, byte[] iv, byte[] aad) | ||
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, | ||
InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException { | ||
return cryptoCore.symmetricEncrypt(secretKey, data, iv, aad); | ||
|
||
} | ||
} |
288 changes: 288 additions & 0 deletions
288
apitest-commons/src/main/java/io/mosip/testrig/apirig/utils/Encrypt.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,288 @@ | ||
package io.mosip.testrig.apirig.utils; | ||
|
||
import java.io.ByteArrayInputStream; | ||
import java.io.IOException; | ||
import java.nio.charset.StandardCharsets; | ||
import java.security.KeyManagementException; | ||
import java.security.NoSuchAlgorithmException; | ||
import java.security.PublicKey; | ||
import java.security.cert.CertificateException; | ||
import java.security.cert.CertificateFactory; | ||
import java.security.cert.X509Certificate; | ||
import java.util.Arrays; | ||
import java.util.Collections; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.stream.IntStream; | ||
|
||
import javax.crypto.SecretKey; | ||
import javax.net.ssl.HttpsURLConnection; | ||
import javax.net.ssl.SSLContext; | ||
import javax.net.ssl.TrustManager; | ||
import javax.net.ssl.X509TrustManager; | ||
import javax.xml.bind.DatatypeConverter; | ||
|
||
import org.apache.commons.codec.binary.Base64; | ||
import org.json.JSONException; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.http.HttpMethod; | ||
import org.springframework.http.HttpRequest; | ||
import org.springframework.http.ResponseCookie; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.http.client.ClientHttpRequestExecution; | ||
import org.springframework.http.client.ClientHttpRequestInterceptor; | ||
import org.springframework.http.client.ClientHttpResponse; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.client.RestTemplate; | ||
import org.springframework.web.reactive.function.client.ClientResponse; | ||
import org.springframework.web.reactive.function.client.WebClient; | ||
import org.springframework.web.util.UriComponentsBuilder; | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import com.fasterxml.jackson.databind.node.ObjectNode; | ||
|
||
import io.mosip.authentication.core.constant.IdAuthConfigKeyConstants; | ||
import io.mosip.kernel.core.http.RequestWrapper; | ||
import io.mosip.kernel.core.util.DateUtils; | ||
import io.mosip.kernel.core.util.HMACUtils2; | ||
import io.mosip.testrig.apirig.dto.EncryptionRequestDto; | ||
import io.mosip.testrig.apirig.dto.EncryptionResponseDto; | ||
@Component | ||
public class Encrypt { | ||
|
||
private static final String SSL = "SSL"; | ||
String publicKeyURL = "${mosip.ida.publicKey-url}"; | ||
String appID = "${application.id}"; | ||
|
||
String keySplitter = "#KEY_SPLITTER#"; | ||
|
||
@Autowired | ||
CryptoUtil cryptoUtil; | ||
|
||
// public EncryptionResponseDto encrypt(EncryptionRequestDto encryptionRequestDto, | ||
// String refId, | ||
// boolean isInternal, | ||
// boolean isBiometrics) throws Exception { | ||
// if (refId == null) { | ||
// refId = getRefId(isInternal, isBiometrics); | ||
// } | ||
// return kernelEncrypt(encryptionRequestDto, refId); | ||
// } | ||
|
||
// private EncryptionResponseDto kernelEncrypt(EncryptionRequestDto encryptionRequestDto, String refId) | ||
// throws Exception { | ||
// ObjectMapper objMapper = new ObjectMapper(); | ||
// | ||
// String identityBlock = objMapper.writeValueAsString(encryptionRequestDto.getIdentityRequest()); | ||
// SecretKey secretKey = cryptoUtil.genSecKey(); | ||
// EncryptionResponseDto encryptionResponseDto = new EncryptionResponseDto(); | ||
// byte[] encryptedIdentityBlock = cryptoUtil.symmetricEncrypt(identityBlock.getBytes(StandardCharsets.UTF_8), | ||
// secretKey); | ||
// encryptionResponseDto.setEncryptedIdentity(Base64.encodeBase64URLSafeString(encryptedIdentityBlock)); | ||
// X509Certificate x509Cert = getCertificate(refId); | ||
// PublicKey publicKey = x509Cert.getPublicKey(); | ||
// byte[] encryptedSessionKeyByte = cryptoUtil.asymmetricEncrypt((secretKey.getEncoded()), publicKey); | ||
// encryptionResponseDto.setEncryptedSessionKey(Base64.encodeBase64URLSafeString(encryptedSessionKeyByte)); | ||
// byte[] byteArr = cryptoUtil.symmetricEncrypt(Encrypt | ||
// .digestAsPlainText(HMACUtils2.generateHash(identityBlock.getBytes(StandardCharsets.UTF_8))).getBytes(), | ||
// secretKey); | ||
// encryptionResponseDto.setRequestHMAC(Base64.encodeBase64URLSafeString(byteArr)); | ||
// return encryptionResponseDto; | ||
// } | ||
|
||
// private String getRefId(boolean isInternal, boolean isBiometrics) { | ||
// String refId; | ||
// if (isBiometrics) { | ||
// if (isInternal) { | ||
// refId = PropertiesReader.readProperty(IdAuthConfigKeyConstants.INTERNAL_BIO_REFERENCE_ID); | ||
// } else { | ||
// refId = PropertiesReader.readProperty(IdAuthConfigKeyConstants.PARTNER_BIO_REFERENCE_ID); | ||
// } | ||
// } else { | ||
// if (isInternal) { | ||
// refId = PropertiesReader.readProperty(IdAuthConfigKeyConstants.INTERNAL_REFERENCE_ID); | ||
// } else { | ||
// refId = PropertiesReader.readProperty(IdAuthConfigKeyConstants.PARTNER_REFERENCE_ID); | ||
// } | ||
// } | ||
// return refId; | ||
// } | ||
|
||
// @SuppressWarnings({"unchecked", "rawtypes"}) | ||
// public X509Certificate getCertificate(String refId) throws IOException, KeyManagementException, | ||
// NoSuchAlgorithmException, JSONException, CertificateException { | ||
// turnOffSslChecking(); | ||
// RestTemplate restTemplate = new RestTemplate(); | ||
// ClientHttpRequestInterceptor interceptor = new ClientHttpRequestInterceptor() { | ||
// | ||
// @Override | ||
// public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) | ||
// throws IOException { | ||
// String authToken = generateAuthToken(); | ||
// if (authToken != null && !authToken.isEmpty()) { | ||
// request.getHeaders().set("Cookie", "Authorization=" + authToken); | ||
// } | ||
// return execution.execute(request, body); | ||
// } | ||
// }; | ||
// | ||
// restTemplate.setInterceptors(Collections.singletonList(interceptor)); | ||
// | ||
// Map<String, String> uriParams = new HashMap<>(); | ||
// UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(publicKeyURL) | ||
// .queryParam("applicationId", appID).queryParam("referenceId", refId); | ||
// ResponseEntity<Map> response = restTemplate.exchange(builder.build(uriParams), HttpMethod.GET, null, Map.class); | ||
// String certificate = (String) ((Map<String, Object>) response.getBody().get("response")).get("certificate"); | ||
// | ||
// certificate = JWSSignAndVerifyController.trimBeginEnd(certificate); | ||
// CertificateFactory cf = CertificateFactory.getInstance("X.509"); | ||
// X509Certificate x509cert = (X509Certificate) cf | ||
// .generateCertificate(new ByteArrayInputStream(java.util.Base64.getDecoder().decode(certificate))); | ||
// return x509cert; | ||
// } | ||
|
||
private static String digestAsPlainText(byte[] data) { | ||
return DatatypeConverter.printHexBinary(data).toUpperCase(); | ||
} | ||
|
||
public static void turnOffSslChecking() throws NoSuchAlgorithmException, KeyManagementException { | ||
// Install the all-trusting trust manager | ||
final SSLContext sc = SSLContext.getInstance(Encrypt.SSL); | ||
sc.init(null, UNQUESTIONING_TRUST_MANAGER, null); | ||
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); | ||
} | ||
|
||
private static final TrustManager[] UNQUESTIONING_TRUST_MANAGER = new TrustManager[]{new X509TrustManager() { | ||
public java.security.cert.X509Certificate[] getAcceptedIssuers() { | ||
return null; | ||
} | ||
|
||
public void checkClientTrusted(java.security.cert.X509Certificate[] arg0, String arg1) | ||
throws CertificateException { | ||
} | ||
|
||
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String arg1) | ||
throws CertificateException { | ||
} | ||
}}; | ||
|
||
// private String generateAuthToken() { | ||
// | ||
// ObjectMapper objMapper = new ObjectMapper(); | ||
// ObjectNode requestBody = objMapper.createObjectNode(); | ||
//// requestBody.put("clientId", env.getProperty("auth-token-generator.rest.clientId")); | ||
//// requestBody.put("secretKey", env.getProperty("auth-token-generator.rest.secretKey")); | ||
//// requestBody.put("appId", env.getProperty("auth-token-generator.rest.appId")); | ||
// requestBody.put("clientId", "mosip-resident-client"); | ||
// requestBody.put("secretKey", "SnZQ6nnVwN9YWvdM"); | ||
// requestBody.put("appId", "resident"); | ||
// RequestWrapper<ObjectNode> request = new RequestWrapper<>(); | ||
// request.setRequesttime(DateUtils.getUTCCurrentDateTime()); | ||
// request.setRequest(requestBody); | ||
// ClientResponse response = WebClient.create(PropertiesReader.readProperty("auth-token-generator.rest.uri")).post() | ||
// .syncBody(request).exchange().block(); | ||
// List<ResponseCookie> list = response.cookies().get("Authorization"); | ||
// if (list != null && !list.isEmpty()) { | ||
// ResponseCookie responseCookie = list.get(0); | ||
// return responseCookie.getValue(); | ||
// } | ||
// return ""; | ||
// } | ||
|
||
public SplittedEncryptedData splitEncryptedData(String data) throws Exception { | ||
//boolean encryptedDataHasVersion = env.getProperty("encryptedDataHasVersion", boolean.class, false); | ||
boolean encryptedDataHasVersion = false; | ||
byte[] dataBytes = io.mosip.kernel.core.util.CryptoUtil.decodeURLSafeBase64(data); | ||
byte[][] splits = splitAtFirstOccurance(dataBytes, keySplitter.getBytes()); | ||
byte[] thumbPrintAndSessionKey = splits[0]; | ||
byte[] sessionKey; | ||
byte[] thumbPrint; | ||
|
||
if (thumbPrintAndSessionKey.length >= 288) { | ||
thumbPrint = Arrays.copyOfRange(thumbPrintAndSessionKey, thumbPrintAndSessionKey.length - 288, | ||
thumbPrintAndSessionKey.length - 256);// Skip the 6 bytes version and take 32 bytes | ||
sessionKey = Arrays.copyOfRange(thumbPrintAndSessionKey, thumbPrintAndSessionKey.length - 256, | ||
thumbPrintAndSessionKey.length); | ||
} else { | ||
throw new Exception("Invalid Encrypted Session Key"); | ||
} | ||
|
||
byte[] encryptedData = splits[1]; | ||
return new SplittedEncryptedData(io.mosip.kernel.core.util.CryptoUtil.encodeToURLSafeBase64(sessionKey), io.mosip.kernel.core.util.CryptoUtil.encodeToURLSafeBase64(encryptedData), digestAsPlainText(thumbPrint)); | ||
} | ||
|
||
public static class SplittedEncryptedData { | ||
private String encryptedSessionKey; | ||
private String encryptedData; | ||
private String thumbprint; | ||
|
||
public SplittedEncryptedData() { | ||
super(); | ||
} | ||
|
||
public SplittedEncryptedData(String encryptedSessionKey, String encryptedData) { | ||
super(); | ||
this.encryptedData = encryptedData; | ||
this.encryptedSessionKey = encryptedSessionKey; | ||
} | ||
|
||
public SplittedEncryptedData(String encryptedSessionKey, String encryptedData, String thumbprint) { | ||
super(); | ||
this.encryptedData = encryptedData; | ||
this.encryptedSessionKey = encryptedSessionKey; | ||
this.thumbprint = thumbprint; | ||
} | ||
|
||
public String getEncryptedData() { | ||
return encryptedData; | ||
} | ||
|
||
public void setEncryptedData(String encryptedData) { | ||
this.encryptedData = encryptedData; | ||
} | ||
|
||
public String getEncryptedSessionKey() { | ||
return encryptedSessionKey; | ||
} | ||
|
||
public void setEncryptedSessionKey(String encryptedSessionKey) { | ||
this.encryptedSessionKey = encryptedSessionKey; | ||
} | ||
|
||
public String getThumbprint() { | ||
return thumbprint; | ||
} | ||
|
||
public void setThumbprint(String thumbprint) { | ||
this.thumbprint = thumbprint; | ||
} | ||
} | ||
|
||
private static byte[][] splitAtFirstOccurance(byte[] strBytes, byte[] sepBytes) { | ||
int index = findIndex(strBytes, sepBytes); | ||
if (index >= 0) { | ||
byte[] bytes1 = new byte[index]; | ||
byte[] bytes2 = new byte[strBytes.length - (bytes1.length + sepBytes.length)]; | ||
System.arraycopy(strBytes, 0, bytes1, 0, bytes1.length); | ||
System.arraycopy(strBytes, (bytes1.length + sepBytes.length), bytes2, 0, bytes2.length); | ||
return new byte[][]{bytes1, bytes2}; | ||
} else { | ||
return new byte[][]{strBytes, new byte[0]}; | ||
} | ||
} | ||
|
||
private static int findIndex(byte arr[], byte[] subarr) { | ||
int len = arr.length; | ||
int subArrayLen = subarr.length; | ||
return IntStream.range(0, len).filter(currentIndex -> { | ||
if ((currentIndex + subArrayLen) <= len) { | ||
byte[] sArray = new byte[subArrayLen]; | ||
System.arraycopy(arr, currentIndex, sArray, 0, subArrayLen); | ||
return Arrays.equals(sArray, subarr); | ||
} | ||
return false; | ||
}).findFirst() // first occurence | ||
.orElse(-1); // No element found | ||
} | ||
} |
420 changes: 267 additions & 153 deletions
420
apitest-commons/src/main/java/io/mosip/testrig/apirig/utils/EncryptionDecrptionUtil.java
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
82 changes: 82 additions & 0 deletions
82
apitest-commons/src/main/java/io/mosip/testrig/apirig/utils/JWSSignAndVerifyController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package io.mosip.testrig.apirig.utils; | ||
|
||
import java.io.BufferedReader; | ||
import java.io.FileInputStream; | ||
import java.io.IOException; | ||
import java.io.InputStreamReader; | ||
import java.io.UnsupportedEncodingException; | ||
import java.security.KeyManagementException; | ||
import java.security.KeyStoreException; | ||
import java.security.NoSuchAlgorithmException; | ||
import java.security.PrivateKey; | ||
import java.security.UnrecoverableEntryException; | ||
import java.security.KeyStore.PrivateKeyEntry; | ||
import java.security.cert.CertificateException; | ||
import java.security.cert.X509Certificate; | ||
import java.security.spec.InvalidKeySpecException; | ||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.Objects; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import com.fasterxml.jackson.databind.node.ObjectNode; | ||
|
||
import io.swagger.annotations.Api; | ||
import lombok.Data; | ||
|
||
|
||
|
||
import org.bouncycastle.operator.OperatorCreationException; | ||
import org.jose4j.jws.JsonWebSignature; | ||
import org.jose4j.lang.JoseException; | ||
|
||
public class JWSSignAndVerifyController { | ||
|
||
private static final String SIGN_ALGO = "RS256"; | ||
|
||
public String sign(String dataToSign, | ||
boolean includePayload, | ||
boolean includeCertificate, | ||
boolean includeCertHash, | ||
String certificateUrl, | ||
String dirPath, | ||
PartnerTypes partnerType, | ||
String organizationName, | ||
boolean keyFileNameByPartnerName) throws JoseException, NoSuchAlgorithmException, UnrecoverableEntryException, | ||
KeyStoreException, CertificateException, IOException, OperatorCreationException { | ||
|
||
KeyMgrUtility keyMgrUtil = new KeyMgrUtility(); | ||
JsonWebSignature jwSign = new JsonWebSignature(); | ||
PrivateKeyEntry keyEntry = keyMgrUtil.getKeyEntry(dirPath, partnerType, organizationName, | ||
keyFileNameByPartnerName); | ||
if (Objects.isNull(keyEntry)) { | ||
throw new KeyStoreException("Key file not available for partner type: " + partnerType.toString()); | ||
} | ||
|
||
PrivateKey privateKey = keyEntry.getPrivateKey(); | ||
X509Certificate x509Certificate = (X509Certificate) keyEntry.getCertificate(); | ||
if (includeCertificate) | ||
jwSign.setCertificateChainHeaderValue(new X509Certificate[] { x509Certificate }); | ||
|
||
if (includeCertHash) | ||
jwSign.setX509CertSha256ThumbprintHeaderValue(x509Certificate); | ||
|
||
if (Objects.nonNull(certificateUrl)) | ||
jwSign.setHeader("x5u", certificateUrl); | ||
|
||
jwSign.setPayload(dataToSign); | ||
jwSign.setAlgorithmHeaderValue(SIGN_ALGO); | ||
jwSign.setKey(privateKey); | ||
jwSign.setDoKeyValidation(false); | ||
if (includePayload) | ||
return jwSign.getCompactSerialization(); | ||
|
||
return jwSign.getDetachedContentCompactSerialization(); | ||
|
||
} | ||
public static String trimBeginEnd(String pKey) { | ||
pKey = pKey.replaceAll("-*BEGIN([^-]*)-*(\r?\n)?", ""); | ||
pKey = pKey.replaceAll("-*END([^-]*)-*(\r?\n)?", ""); | ||
pKey = pKey.replaceAll("\\s", ""); | ||
return pKey; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
453 changes: 453 additions & 0 deletions
453
apitest-commons/src/main/java/io/mosip/testrig/apirig/utils/KeyMgrUtility.java
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 20 additions & 0 deletions
20
apitest-commons/src/main/java/io/mosip/testrig/apirig/utils/PartnerTypes.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package io.mosip.testrig.apirig.utils; | ||
|
||
public enum PartnerTypes { | ||
|
||
DEVICE("device"), | ||
RELYING_PARTY("rp"), | ||
FTM("ftm"), | ||
EKYC("ekyc"), | ||
MISP("misp"); | ||
|
||
private String filePrepend; | ||
|
||
private PartnerTypes(String filePrepend) { | ||
this.filePrepend = filePrepend; | ||
} | ||
|
||
public String getFilePrepend() { | ||
return this.filePrepend; | ||
} | ||
} |
Oops, something went wrong.