Java 如何使用数字证书创建Web服务

Java 如何使用数字证书创建Web服务,java,web-services,security,digital-signature,Java,Web Services,Security,Digital Signature,我必须建立一个带有数字证书的网络服务,但我在这方面没有经验,我有一些例子,但这对我来说还不够。在下面的代码中,我可以从JKS文件中获取公钥和私钥,对字符串进行加密,并验证该字符串是否已分配。但我对我应该使用谁有一些疑问: 我有一个私钥和一个公钥。如果我有多个客户调用我的Web服务,他们两个都需要公钥吗?私钥呢 如何将公钥发送到客户端?是文件还是字符串?我的公共测试密钥的返回为: 公钥:Sun RSA公钥,2048位 模数:1725032489261248685850742968544883970

我必须建立一个带有数字证书的网络服务,但我在这方面没有经验,我有一些例子,但这对我来说还不够。在下面的代码中,我可以从JKS文件中获取公钥和私钥,对字符串进行加密,并验证该字符串是否已分配。但我对我应该使用谁有一些疑问:

  • 我有一个私钥和一个公钥。如果我有多个客户调用我的Web服务,他们两个都需要公钥吗?私钥呢

  • 如何将公钥发送到客户端?是文件还是字符串?我的公共测试密钥的返回为:

  • 公钥:Sun RSA公钥,2048位 模数:17250324892612486858507429685448839704055777462217619737452934774822672851497966978790916432466790842915878683120882004958695145419939098968836614824888409393052061936762455389263916348884908835001481590512979961376093665985176086582620326688971144157926968064917610077028818131909416605240046026228844714588221891425654992455455846135152245033503553286312978619541722235228388013887009488301495951905133704760137236960349458111717499961995019021977295294912070129505927611114331851407796798585518424426757876237265884912360355209124912153937505471115177310252984915833469781596755813935167181407292034238159965045653 公众指数: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();  
    }  
    
    /**
    *@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将其发送到客户端: