Чтение pfx-файла с USB-токена с помощью Java
Я пытаюсь подписать pdf-документ в java с помощью электронного токена USB. Я хочу прочитать подпись с USB-токена safenet (alladin etoken pro 72 k(Java)) и прикрепить к pdf с помощью кода java. Я сделал цифровую подпись подписи с помощью ключа, хранящегося на моем локальном компьютере. Но я хочу знать, как то же самое можно сделать с помощью электронного токена USB.
3 ответа
Смысл USB-токена для подписи в том, что никто не может прочитать секретный ключ с этого устройства. Итак, вы отправили хеш на токен, и он отправит вам подпись обратно.
Чтобы это работало, вам нужен JCE-провайдер, который может общаться с токеном. Обычно это делается либо PKCS#11 (для этого токен предоставляет библиотеку), либо токен предоставляет драйвер MSCAPI (под окнами).
Оба могут использоваться в Java, способ PKCS # 11 может быть немного сложнее в настройке, но по моему опыту это лучше для автоматической подписи, потому что в случае MSCAPI вам часто нужно вводить PIN-код токена вручную.
Если ваш токен распознается Windows, следующая команда должна увидеть и перечислить его ключ:
keytool -list -storetype Windows-MY
Затем хранилище ключей Windows можно использовать для получения дескриптора ключа для подписи, но вы также можете использовать его для экспорта копии открытого ключа.
Вы можете использовать поставщика SUN PKCS11 для ссылки на ключи в Etoken. Вы можете просто попробовать приведенный ниже код
String pkcs11Config = "name=eToken\nlibrary=C:\\Windows\\System32\\eps2003csp11.dll";
java.io.ByteArrayInputStream pkcs11ConfigStream = new java.io.ByteArrayInputStream(pkcs11Config.getBytes());
sun.security.pkcs11.SunPKCS11 providerPKCS11 = new sun.security.pkcs11.SunPKCS11("pkcs11Config");
java.security.Security.addProvider(providerPKCS11);
// Get provider KeyStore and login with PIN
String pin = "12345678";
java.security.KeyStore keyStore = java.security.KeyStore.getInstance("PKCS11", providerPKCS11);
KeyStore keyStore=KeyStore.getInstance("PKCS11",providerPKCS11);
keyStore.load(null, pin.toCharArray());
// Enumerate items (certificates and private keys) in the KeyStore
java.util.Enumeration<String> aliases = keyStore.aliases();
String alias = null;
while (aliases.hasMoreElements()) {
alias = aliases.nextElement();
System.out.println(alias);
}
Попробуйте этот код
import com.lowagie.text.pdf.*;
import com.lowagie.text.Rectangle;
//import com.lowagie.text.pdf.pdfSignatureAppearance;
//import com.lowagie.text.pdf.pdfStamper;
import java.security.*;
import java.io.*;
import java.awt.*;
import java.security.cert.*;
import java.lang.*;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.cert.CertPath;
import java.security.cert.CertificateFactory;
import java.util.ArrayList;
import java.util.List;
public class pdfsign1{
public static void main(String args[]) {
try {
KeyStore ks = KeyStore.getInstance("pkcs12");
ks.load(new FileInputStream("my_private_key.pfx"), "my_password".toCharArray());
String alias = (String)ks.aliases().nextElement();
PrivateKey key = (PrivateKey)ks.getKey(alias, "my_password".toCharArray());
Certificate[] chain = ks.getCertificateChain(alias);[/b]
PdfReader reader = new PdfReader("original.pdf");
FileOutputStream fout = new FileOutputStream("signed.pdf");
PdfStamper stp = PdfStamper.createSignature(reader, fout, '\0');
PdfSignatureAppearance sap = stp.getSignatureAppearance();
//sap.setCrypto(key, chain, null, PdfSignatureAppearance.WINCER_SIGNED);
sap.setReason("I'm the author");
sap.setLocation("Lisbon");
// comment next line to have an invisible signature
sap.setVisibleSignature(new Rectangle(100, 100, 200, 200), 1, null);
stp.close();
}
catch(Exception e) {}
}
}