デジタル証明書を使用して Web サービスを構築する必要がありますが、この分野での経験がありません。いくつかの例を入手しましたが、まだ十分ではありませんでした。以下のコードでは、JKS ファイルから公開鍵と秘密鍵を取得し、文字列を暗号化し、その文字列が割り当てられているかどうかを確認できます。しかし、私はそれを誰に使うべきかについていくつか疑問があります:
私は 1 つの秘密鍵と 1 つの公開鍵を持っています。複数のクライアントが Web サービスを呼び出している場合、両方のクライアントが公開鍵を持っている必要がありますか? そして秘密鍵?
公開鍵をクライアントに送信するにはどうすればよいですか? ファイルまたは文字列ですか? 私の公開テストキーの戻り値は次のとおりです。
PUBLIC KEY: Sun RSA 公開鍵、2048 ビット モジュラス: 公開指数: 65537
コードでは、署名が正しいかどうかのみを確認できます。それを解読して実際の値を取得することはできません。
java.io.File をインポートします。java.io.FileInputStream をインポートします。java.io.InputStream をインポートします。java.security.Key をインポートします。java.security.KeyStore をインポートします。java.security.PrivateKey をインポートします。java.security.PublicKey をインポートします。java.security.Signature をインポートします。java.security.cert.Certificate をインポートします。
public class 証明書 {
/** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { String txt = "TEST_STRING"; File certificado = new File("C:\\temp\\teste.jks"); PrivateKey privateKey = getPrivateKeyFromFile(certificado, "TESTE", "123"); System.out.println("PRIVATE KEY: " + privateKey.toString()); PublicKey publicKey = getPublicKeyFromFile(certificado, "TESTE", "123"); System.out.println("PUBLIC KEY: " + publicKey.toString()); //a chave privada serve pra encriptar os dados. byte[] txtAssinado = createSignature( privateKey, txt.getBytes() ); System.out.println("txtAssinado: " + txt2Hexa( txtAssinado ) ); if( verifySignature( publicKey, txt.getBytes(), txtAssinado ) ) { System.out.println("Assinatura OK!"); } else { System.out.println("Assinatura NOT OK!"); } } public static PrivateKey getPrivateKeyFromFile( File cert, String alias, String password ) throws Exception { KeyStore ks = KeyStore.getInstance ( "JKS" ); char[] pwd = password.toCharArray(); InputStream is = new FileInputStream( cert ); ks.load( is, pwd ); is.close(); Key key = ks.getKey( alias, pwd ); if( key instanceof PrivateKey ) { return (PrivateKey) key; } return null; } /** * Retorna a assinatura para o buffer de bytes, usando a chave privada. * @param key PrivateKey * @param buffer Array de bytes a ser assinado. */ public static byte[] createSignature( PrivateKey key, byte[] buffer ) throws Exception { Signature sig = Signature.getInstance("MD2withRSA"); sig.initSign(key); sig.update(buffer, 0, buffer.length); return sig.sign(); } /** * Verifica a assinatura para o buffer de bytes, usando a chave pública. * @param key PublicKey * @param buffer Array de bytes a ser verficado. * @param sgined Array de bytes assinado (encriptado) a ser verficado. */ public static boolean verifySignature( PublicKey key, byte[] buffer, byte[] signed ) throws Exception { Signature sig = Signature.getInstance("MD2withRSA"); sig.initVerify(key); sig.update(buffer, 0, buffer.length); return sig.verify( signed ); } /** * Extrai a chave pública do arquivo. */ public static PublicKey getPublicKeyFromFile( File cert, String alias, String password ) throws Exception { KeyStore ks = KeyStore.getInstance ( "JKS" ); char[] pwd = password.toCharArray(); InputStream is = new FileInputStream( cert ); ks.load( is, pwd ); Key key = ks.getKey( alias, pwd ); Certificate c = ks.getCertificate( alias ); PublicKey p = c.getPublicKey(); return p; } public static String txt2Hexa(byte[] bytes) { if( bytes == null ) return null; String hexDigits = "0123456789abcdef"; StringBuffer sbuffer = new StringBuffer(); for (int i = 0; i < bytes.length; i++) { int j = ((int) bytes[i]) & 0xFF; sbuffer.append(hexDigits.charAt(j / 16)); sbuffer.append(hexDigits.charAt(j % 16)); } return sbuffer.toString(); }
}