我必须用数字证书建立一个网络服务,但我在这方面没有经验,我有一些例子,但对我来说还不够。在下面的代码中,我可以从 JKS 文件中获取公钥和私钥,加密字符串并验证是否分配了该字符串。但我对我应该使用谁有一些疑问:
我有 1 个私钥和 1 个公钥。如果我有多个客户调用我的网络服务,他们都需要有公钥吗?和私钥?
我应该如何将公钥发送给客户端?是文件还是字符串?我的公共测试密钥的返回是:
公钥: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;
公共类证书{
/** * @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(); }
}