Я пытаюсь подписать конкретную строку закрытым ключом, который я получу из сертификата pem. Этот сертификат зашифрован парольной фразой. Формат сертификата (файла .pem) примерно такой:
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,A60C80692F0FEB16
Fq/awhS....
+..
+..
+..
+..
+....detSug=
-----END RSA PRIVATE KEY-----
Код, который я написал для получения открытого и закрытого ключей из этого сертификата:
import java.io.FileReader;
import java.io.IOException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import org.bouncycastle.asn1.ASN1Generator;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.openssl.PEMDecryptorProvider;
import org.bouncycastle.openssl.PEMEncryptedKeyPair;
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import sun.misc.BASE64Encoder;
class MainClass{
public static void main(String args[]){
try{
PrivateKey pk = readPrivateKey("C:/Input/CERT.pem","passphrase");
PublicKey pubk = readPublicKey("C:/Input/CERT.pem","passphrase");
byte[] data = "ABCEFG20150520163306".getBytes("UTF8");
Signature sig = Signature.getInstance("SHA1WithRSA");
sig.initSign(pk);
sig.update(data);
byte[] signatureBytes = sig.sign();
System.out.println("Singature:" + new BASE64Encoder().encode(signatureBytes));
sig.initVerify(pubk);
sig.update(data);
System.out.println(sig.verify(signatureBytes));
}catch(Exception e){
e.printStackTrace();
}
}
private static PrivateKey readPrivateKey(String privateKeyPath, String keyPassword) throws IOException {
FileReader fileReader = new FileReader(privateKeyPath);
PEMParser keyReader = new PEMParser(fileReader);
JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
PEMDecryptorProvider decryptionProv = new JcePEMDecryptorProviderBuilder().build(keyPassword.toCharArray());
System.out.println(keyReader.getClass());
Object keyPair = keyReader.readObject();
PrivateKeyInfo keyInfo;
System.out.println(keyPair.getClass());
if (keyPair instanceof PrivateKeyInfo) {
System.out.println("Correct instance found");
PEMKeyPair decryptedKeyPair = ((PEMEncryptedKeyPair) keyPair).decryptKeyPair(decryptionProv);
keyInfo = decryptedKeyPair.getPrivateKeyInfo();
} else {
keyInfo = ((PEMKeyPair) keyPair).getPrivateKeyInfo();
}
keyReader.close();
return converter.getPrivateKey(keyInfo);
}
private static PublicKey readPublicKey(String privateKeyPath, String keyPassword) throws IOException {
FileReader fileReader = new FileReader(privateKeyPath);
PEMParser keyReader = new PEMParser(fileReader);
JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
PEMDecryptorProvider decryptionProv = new JcePEMDecryptorProviderBuilder().build(keyPassword.toCharArray());
Object keyPair = keyReader.readObject();
SubjectPublicKeyInfo keyInfo;
if (keyPair instanceof PEMEncryptedKeyPair) {
PEMKeyPair decryptedKeyPair = ((PEMEncryptedKeyPair) keyPair).decryptKeyPair(decryptionProv);
keyInfo = decryptedKeyPair.getPublicKeyInfo();
} else {
keyInfo = ((PEMKeyPair) keyPair).getPublicKeyInfo();
}
keyReader.close();
return converter.getPublicKey(keyInfo);
}
}
Этот код работает нормально, но теперь я должен сделать то же самое для сертификата ASN1, который выглядит следующим образом
Bag Attributes
localKeyID: 01 00 00 00
friendlyName: le-d5391255-2e94-48fe-8327-caca5d9aa498<Microsoft CSP Name: Microsoft Enhanced Cryptographic Provider v1.0
Key Attributes
X509v3 Key Usage: 10
-----BEGIN PRIVATE KEY-----
MIIEvwIBA....
+..
+..
+..
+..
+....N5kNrDV0Yg==
-----END PRIVATE KEY-----
Bag Attributes
localKeyID: 00 01 00 00
1.3.6.1.4.1.322.17.3.92: 00 08 00 00
1.3.6.1.4.1.311.17.3.20: 15 0D 78 6A D0 18 CB A2 D1 7F D1 C2 B2 7A E0 53 70 D7 ED F9
1.3.6.1.4.1.313.17.3.79: 46 00 61 00 9E 00 65 00 73 00 73 00 61 00 2D 00 50 00 43 00 00 00
subject=/C=SG/O=Netrust Certificate Authority 1/OU=Netrust CA1 (Server)/OU=ABC-XYZ Private Limited/CN=QICERT
issuer=/C=SG/O=Netrust Certificate Authority 1/OU=Netrust CA
-----BEGIN CERTIFICATE-----
MIIE5DCCA8yg....
+..
+..
+..
+..
+....Y7LF
Byuyq1Pe4QY=
-----END CERTIFICATE-----
Bag Attributes
1.3.6.1.4.1.311.17.3.92: 00 08 00 00
1.3.1.1.4.1.221.17.3.20: 1D 44 89 B2 45 26 7F 3F 6B 92 C5 3A 7B 72 63 CA D2 70 2A DD
subject=/C=SG/O=Netrust Certificate Authority 1/OU=Netrust CA1
issuer=/C=SG/O=Netrust Certificate Authority 1/OU=Netrust CA1
-----BEGIN CERTIFICATE-----
MIIESTCCAzGgAwI....
+..
+..
+..
+..
+....Y7LF
iY44mB2Sev4/02GkW7
-----END CERTIFICATE-----
Когда я запускаю этот код для этого нового сертификата, я получаю следующую ошибку:
java.lang.ClassCastException: org.bouncycastle.asn1.pkcs.PrivateKeyInfo cannot be cast to org.bouncycastle.openssl.PEMEncryptedKeyPair
at MainClass.readPrivateKey(MainClass.java:92)
at MainClass.main(MainClass.java:47)
На основании этого сообщения об ошибке я пытаюсь изменить свой код, чтобы получить пару закрытого и открытого ключей для типа ASN1, но я не могу это сделать.
Я использую это и это в качестве справки.
Спасибо!