Java 如何使用数字证书创建Web服务
我必须建立一个带有数字证书的网络服务,但我在这方面没有经验,我有一些例子,但这对我来说还不够。在下面的代码中,我可以从JKS文件中获取公钥和私钥,对字符串进行加密,并验证该字符串是否已分配。但我对我应该使用谁有一些疑问:Java 如何使用数字证书创建Web服务,java,web-services,security,digital-signature,Java,Web Services,Security,Digital Signature,我必须建立一个带有数字证书的网络服务,但我在这方面没有经验,我有一些例子,但这对我来说还不够。在下面的代码中,我可以从JKS文件中获取公钥和私钥,对字符串进行加密,并验证该字符串是否已分配。但我对我应该使用谁有一些疑问: 我有一个私钥和一个公钥。如果我有多个客户调用我的Web服务,他们两个都需要公钥吗?私钥呢 如何将公钥发送到客户端?是文件还是字符串?我的公共测试密钥的返回为: 公钥:Sun RSA公钥,2048位 模数:1725032489261248685850742968544883970
/**
* @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();
}
/**
*@param args
*@抛出异常
*/
公共静态void main(字符串[]args)引发异常{
String txt=“测试字符串”;
文件certificado=新文件(“C:\\temp\\teste.jks”);
PrivateKey PrivateKey=getPrivateKeyFromFile(certificado,“TESTE”,“123”);
System.out.println(“私钥:+privateKey.toString());
PublicKey PublicKey=getPublicKeyFromFile(certificado,“TESTE”,“123”);
System.out.println(“公钥:+publicKey.toString());
//一辆私家车为护墙板提供服务。
byte[]txtAssinado=createSignature(privateKey,txt.getBytes());
System.out.println(“txtAssinado:+txt2Hexa(txtAssinado));
if(verifySignature(publicKey,txt.getBytes(),txtAssinado)){
System.out.println(“Assinatura OK!”);
}否则{
System.out.println(“Assinatura NOT OK!”);
}
}
public static PrivateKey getPrivateKeyFromFile(文件证书、字符串别名、字符串密码)引发异常{
KeyStore ks=KeyStore.getInstance(“JKS”);
char[]pwd=password.toCharArray();
InputStream is=新文件InputStream(证书);
ks.荷载(is,pwd);
is.close();
Key Key=ks.getKey(别名,pwd);
if(PrivateKey的密钥实例){
返回(私钥)键;
}
返回null;
}
/**
*一个字节缓冲区的辅助程序,一个私有程序。
*@param-key-PrivateKey
*@param buffer Array de bytes a ser assinado。
*/
公共静态字节[]createSignature(私钥密钥,字节[]缓冲区)引发异常{
Signature sig=Signature.getInstance(“MD2withRSA”);
sig.initSign(key);
sig.update(buffer,0,buffer.length);
返回sig.sign();
}
/**
*验证一个字节缓冲区的辅助,使用一个chave pública。
*@param-key公钥
*@param buffer Array de bytes a ser verficado。
*@param sgined数组de bytes assinado(encriptado)一个ser verficado。
*/
公共静态布尔验证签名(公钥,字节[]缓冲区,字节[]签名)引发异常{
Signature sig=Signature.getInstance(“MD2withRSA”);
信号初始化验证(密钥);
sig.update(buffer,0,buffer.length);
返回信号验证(签名);
}
/**
*阿奎沃岛上的一家餐馆。
*/
公共静态公钥getPublicKeyFromFile(文件证书、字符串别名、字符串密码)引发异常{
KeyStore ks=KeyStore.getInstance(“JKS”);
char[]pwd=password.toCharArray();
InputStream is=新文件InputStream(证书);
ks.荷载(is,pwd);
Key Key=ks.getKey(别名,pwd);
证书c=ks.getCertificate(别名);
PublicKey p=c.getPublicKey();
返回p;
}
公共静态字符串txt2Hexa(字节[]字节){
if(bytes==null)返回null;
字符串hexDigits=“0123456789abcdef”;
StringBuffer sbuffer=新的StringBuffer();
对于(int i=0;i
}你为什么需要它?如果只是为了加密通信,您可以使用SSL/TLS在传输级别进行加密。如果是用于身份验证,我建议使用WS-Policy框架构建一个健壮的webservice堆栈(例如ApacheCXF和Metro)。它会为你处理低级加密的东西
(当然,您可以在传输级别上使用身份验证,在消息级别上使用加密,但前者将代码与应用程序服务器耦合,后者的速度非常慢。)在本教程之后,我决定使用ws-security:
谢谢 您可以通过将公钥指向此url将其发送到客户端: