RSA と SHA-1 でデータに署名したいのですが、データのサイズが大きすぎます。
このスレッドを参照してください: Using SHA1 and RSA with java.security.Signature vs. MessageDigest and Cipher、ハッシュ化されたデータを暗号化しようとしています。
PKCS12またはPKCS11プロバイダーを使用して秘密鍵をロードすると、問題ありません。署名と暗号化されたデータは同じです。しかし、SunMSCAPIプロバイダーを使用すると問題が発生し、異なる結果が得られます。
これは私のコードです:
public static Vector<PrivateKey> privateKeyArr = new Vector<PrivateKey>();
private static PrivateKey privateKey;
public static void load_win_store() {
try {
KeyStore store = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
store.load(null, null);
Enumeration enumer = store.aliases();
while (enumer.hasMoreElements()) {
String alias = enumer.nextElement().toString();
X509Certificate x509 = (X509Certificate) store.getCertificate(alias);
PrivateKey privateKey = (PrivateKey) store.getKey(alias, null);
privateKeyArr.add(privateKey);
}
} catch (Exception ex) {
ex.printStackTrace();
}
privateKey = privateKeyArr.get(0);
}
public static void main(String[] args) {
try {
String plaintext = "abc";
load_win_store();
Signature instance = Signature.getInstance("SHA1withRSA");
instance.initSign(privateKey);
instance.update((plaintext).getBytes());
byte[] signature = instance.sign();
MessageDigest _sha1 = MessageDigest.getInstance("SHA1");
byte[] _digest = _sha1.digest(plaintext.getBytes());
DERObjectIdentifier sha1oid_ = new DERObjectIdentifier("1.3.14.3.2.26");
AlgorithmIdentifier sha1aid_ = new AlgorithmIdentifier(sha1oid_, null);
DigestInfo di = new DigestInfo(sha1aid_, _digest);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] cipherText = cipher.doFinal(di.getDEREncoded());
System.out.println("Cipher text: " + byteArray2Hex(cipherText));
System.out.println("Signature: " + byteArray2Hex(signature));
} catch (Exception e) {
e.printStackTrace();
}
}
byteArray2Hex メソッド:
private static final char[] hex = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
private static String byteArray2Hex(byte[] bytes) {
StringBuilder sb = new StringBuilder(bytes.length * 2);
for (final byte b : bytes) {
sb.append(hex[(b & 0xF0) >> 4]);
sb.append(hex[b & 0x0F]);
}
return sb.toString();
}
そして、これが私の結果です:
Cipher text: a70c2d53a4fb6eb68f91ca46fcaae61c30544...
Signature: 63d39af150212aa1b3a2539fcecfd9d744...
助けてください、どうもありがとう!