Как правильно расшифровать данные в ApplePay на Java?JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Как правильно расшифровать данные в ApplePay на Java?

Сообщение Anonymous »

Добрый день.
Я пытаюсь интегрироваться с ApplePay, но возникла проблема. Я не могу расшифровать данные, полученные от ApplePay.
Вот мой код:
Вот моя функция получения ключа конкатенации:

Код: Выделить всё

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Concat {

public byte[] concatKDF(String hashAlg, byte[] z, int keyDataLen, byte[] algorithmID, byte[] partyUInfo, byte[] partyVInfo) throws NoSuchAlgorithmException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
baos.write(algorithmID);
baos.write(partyUInfo);
baos.write(partyVInfo);
} catch (IOException e) {
throw new RuntimeException(e);
}

byte[] otherInfo = baos.toByteArray();
return concatKDF(hashAlg, z, keyDataLen, otherInfo);
}

public byte[] concatKDF(String hashAlg, byte[] z, int keyDataLen, byte[] otherInfo) throws NoSuchAlgorithmException
{
byte[] key = new byte[keyDataLen];
MessageDigest md = MessageDigest.getInstance(hashAlg);
int hashLen = md.getDigestLength();
int reps = keyDataLen / hashLen;
for(int i=1;i> 24);
res[1] = (byte) ((i >>> 16) & 0xFF);
res[2] = (byte) ((i >>> 8) & 0xFF);
res[3] = (byte) (i &  0xFF);
return res;
}
}

здесь я пытаюсь восстановить симметричный ключ и расшифровать данные:

Код: Выделить всё

import org.bouncycastle.util.encoders.Hex;

import javax.crypto.Cipher;
import javax.crypto.KeyAgreement;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.FileInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

public class AppleDecryption {

private final static byte[] Z = "SHA-256".getBytes(StandardCharsets.UTF_8);
private final static byte[] partyUInfo = "Apple".getBytes(StandardCharsets.US_ASCII);

public static void main(String[] args) throws Exception {
String data = "data i need to decrypt";
PrivateKey merchantPrivateKey = loadPrivateKeyFromPKCS12("path_to_my_p12_key","password_of_key!","alias");
PublicKey publicKey = loadPublicKey();
X509Certificate certificate = loadCertificate();

//here i restore symmetric key according first step (1) this doc: https://developer.apple.com/documentation/passkit_apple_pay_and_wallet/apple_pay/payment_token_format_reference/restoring_the_symmetric_key?language=objc
KeyAgreement agreement = KeyAgreement.getInstance("ECDH");
agreement.init(merchantPrivateKey);
agreement.doPhase(publicKey, true);
byte[] sharedSecret = agreement.generateSecret();

//here i restore symmetric key according second step (2) this doc: https://developer.apple.com/documentation/passkit_apple_pay_and_wallet/apple_pay/payment_token_format_reference/restoring_the_symmetric_key?language=objc
byte[] merchantIdentifierTlv = certificate.getExtensionValue("1.2.840.113635.100.6.32");
byte[] merchantIdentifier = new byte[32];
System.arraycopy(merchantIdentifierTlv, 4, merchantIdentifier, 0, 32);
byte[] partyVInfo = Hex.decode(merchantIdentifier);
Concat concat = new Concat();
byte[] symmetricKey = concat.concatKDF("SHA-256", Z, 32, sharedSecret, partyUInfo, partyVInfo, null, null);

//here i try to decrypt data with symmetricKey that i got before according step 4 this doc:  https://developer.apple.com/documentation/passkit_apple_pay_and_wallet/apple_pay/payment_token_format_reference
SecretKeySpec key = new SecretKeySpec(symmetricKey, "AES");
byte[] ivBytes = new byte[16];
IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
Cipher aesCipher = Cipher.getInstance("AES/GCM/NoPadding");
aesCipher.init(Cipher.DECRYPT_MODE, key, ivSpec);

aesCipher.doFinal(Base64.getDecoder().decode(data));

}

public static PrivateKey loadPrivateKeyFromPKCS12(String keyStorePath, String keyStorePassword, String alias) throws Exception {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
InputStream keyStoreData = new FileInputStream(keyStorePath);
keyStore.load(keyStoreData, keyStorePassword.toCharArray());

KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(keyStorePassword.toCharArray());
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(alias, entryPassword);

PrivateKey privateKey = privateKeyEntry.getPrivateKey();
keyStoreData.close();
return privateKey;
}

public static X509Certificate loadCertificate() throws Exception {
String filename = "path_to_apple_pay.cer";
FileInputStream fis = new FileInputStream(filename);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate certificate = (X509Certificate) cf.generateCertificate(fis);
fis.close();

return certificate;
}

private static PublicKey loadPublicKey() throws Exception {
String publicKeyBase64 = "my_public_key";
byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyBase64);
KeyFactory keyFactory = KeyFactory.getInstance("EC");
return keyFactory.generatePublic(new X509EncodedKeySpec(publicKeyBytes));
}
}

Я всегда получаю исключение javax.crypto.AEADBadTagException: несоответствие тегов! ошибка.
Буду рад любой помощи.
Что я делаю не так?
Может быть, у кого-то тоже есть такая проблема или он может мне помочь?
Я попробовал несколько способов загрузки закрытых и открытых ключей, попробовал несколько способов создания симметричных ключей и расшифровки данных, но результат всегда один и тот же: javax.crypto.AEADBadTagException: несоответствие тегов! ошибка

Подробнее здесь: https://stackoverflow.com/questions/787 ... ay-in-java
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»