我必须建立一个带有数字证书的网络服务,但我在这方面没有经验,我有一些例子,但对我来说还不够。在下面的代码中,我可以从 JKS 文件获取公钥和私钥,加密字符串并验证是否分配了该字符串。但我对谁应该使用它有一些疑问:
我有 1 个私钥和 1 个公钥。如果我有多个客户调用我的网络服务,他们都需要拥有公钥吗?和私钥?
我应该如何将公钥发送给客户端?是文件还是字符串?我的公共(public)测试 key 的返回是:
公钥:Sun RSA 公钥,2048 位 模数: 1725032489261248685850742968544883970405577746221761973745293477482267285149796697879091643246679084291587868312088200 495869514541993909896883661482488840939305206193676245538926391634888490883500148159051297996137609366598517608658262032668 897114415792696806491761007702881813190941660524004602622884471458822189142565499245545584613515224503350355328631297861954 172223522838801388700948830149595190513370476013723696034945811171749996199501902197729529491207012950592761111433185140779 679858551842442675787623726588491236035520912491215393750547111517731025298491583346978159675581393516718140729203423815996 5045653 公共(public)指数: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)类证书{
/** * @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(); }
}
最佳答案
为什么需要它?如果只是为了加密通信,您可以使用 SSL/TLS 在传输级别上实现这一点。如果是为了身份验证,我建议使用带有 WS-Policy 框架的强大的 Web 服务堆栈(例如 Apache CXF 和 Metro)。它会为您处理低级加密内容。
(当然,您可以在传输级别使用身份验证,并在消息级别使用加密,但第一个将您的代码与应用程序服务器耦合,而后者速度非常慢。)
关于java - 如何使用数字证书创建Web服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11234776/