2011-03-23 2 views

답변

6

다음은 구현 예입니다. 테스트 기능이 제공됩니다 (아래 참조).

private static byte[] signData(OutputStream target, 
           PrivateKey key, String[] data) 
    throws IOException, GeneralSecurityException 
{ 
    Signature sig = Signature.getInstance("SHA1withRSA"); 
    sig.initSign(key); 
    DataOutputStream dOut = 
     new DataOutputStream(new SignatureOutputStream(target, sig)); 


    for(String s : data) { 
     dOut.writeUTF(s); 
    } 
    byte[] signature = sig.sign(); 
    return signature; 
} 


private static void verify(PublicKey key, byte[] signature, 
           byte[] data) 
    throws IOException, GeneralSecurityException 
{ 
    Signature sig = Signature.getInstance("SHA1withRSA"); 
    sig.initVerify(key); 

    ByteArrayOutputStream collector = 
     new ByteArrayOutputStream(data.length); 
    OutputStream checker = new SignatureOutputStream(collector, sig); 
    checker.write(data); 
    if(sig.verify(signature)) { 
     System.err.println("Signature okay"); 
    } 
    else { 
     System.err.println("Signature falsed!"); 
    } 
} 


/** 
* a test method. 
*/ 
public static void main(String[] params) 
    throws IOException, GeneralSecurityException 
{ 
    if(params.length < 1) { 
     params = new String[] {"Hello", "World!"}; 
    } 

    KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA"); 
    KeyPair pair = gen.generateKeyPair(); 


    ByteArrayOutputStream arrayStream = new ByteArrayOutputStream(); 

    byte[] signature = signData(arrayStream, pair.getPrivate(), params); 
    byte[] data = arrayStream.toByteArray(); 

    verify(pair.getPublic(), signature, data); 

    // change one byte by one 
    data[3]++; 

    verify(pair.getPublic(), signature, data); 

    data = arrayStream.toByteArray(); 

    verify(pair.getPublic(), signature, data); 

    // change signature 
    signature[4]++; 

    verify(pair.getPublic(), signature, data); 

} 

주요 방법은 새로운 (랜덤) 개인 키의 명령 라인 파라미터에 서명하고 대응을 확인 : 여기

package de.fencing_game.paul.examples; 

import java.io.*; 
import java.security.*; 

/** 
* This class provides an outputstream which writes everything 
* to a Signature as well as to an underlying stream. 
*/ 
public class SignatureOutputStream 
    extends OutputStream 
{ 

    private OutputStream target; 
    private Signature sig; 

    /** 
    * creates a new SignatureOutputStream which writes to 
    * a target OutputStream and updates the Signature object. 
    */ 
    public SignatureOutputStream(OutputStream target, Signature sig) { 
     this.target = target; 
     this.sig = sig; 
    } 

    public void write(int b) 
     throws IOException 
    { 
     write(new byte[]{(byte)b}); 
    } 

    public void write(byte[] b) 
     throws IOException 
    { 
     write(b, 0, b.length); 
    } 

    public void write(byte[] b, int offset, int len) 
     throws IOException 
    { 
     target.write(b, offset, len); 
     try { 
      sig.update(b, offset, len); 
     } 
     catch(SignatureException ex) { 
      throw new IOException(ex); 
     } 
    } 

    public void flush() 
     throws IOException 
    { 
     target.flush(); 
    } 

    public void close() 
     throws IOException 
    { 
     target.close(); 
    } 
} 

이를 사용하는 방법을 보여주는 몇 가지 시험 방법이다 공개 키. 그것은 약간 변경된 데이터와 서명으로 다시 점검합니다.

물론 서명을 확인하려면 SignatureInputStream이 더 유용 할 것입니다. 정확히 같은 방식으로 만들 수 있습니다.

관련 문제