2013-10-01 85 views
0

我試圖使用私鑰簽名消息摘要以生成簽名,然後使用公鑰驗證簽名以獲取消息摘要。我想與這兩個消息摘要進行比較,但是我得到一個關於「java.security.SignatureException:簽名長度不正確:250但期望128」的錯誤。使用簽名和驗證簽名的差異結果

,當我試圖打印出Arrays.toString(數據2),其全0 我也試圖跟隨鏈接:Verify the Signature

public void firstDigitalSignature() throws IOException, NoSuchAlgorithmException, Throwable 
{ 

    //*Generate Message Digest1* 
    byte[] buffer=null; 
    buffer = new byte[(int) inputFile1.length()]; 
    FileInputStream fis = new FileInputStream(inputFile1); 
    fis.read(buffer); 
    MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); 
    messageDigest.update(buffer); 
    digestBytes = messageDigest.digest(); 
    //convert the byte to hex format method 2 
    StringBuffer hexString = new StringBuffer(); 
    for(int i=0;i<digestBytes.length;i++){ 
     hexString.append(Integer.toHexString(0xFF & digestBytes[i])); 
    } 
    System.out.println("Message Digest-1: "+hexString.toString()); 

    //*Using private key to encrypt the image-Digital signauture1 * 
    Signature signature = Signature.getInstance("SHA256withRSA"); 
    signature.initSign(privateKey); 
    signature.update(digestBytes); 
    encryptmd= signature.sign(); 
    StringBuffer hexString2 = new StringBuffer(); 
    for(int i=0;i<encryptmd.length;i++){ 
      hexString2.append(Integer.toHexString(0xFF & encryptmd[i])); 
      x=hexString2.toString(); 
      File file = new File("c://Directroy111"); 
      if (!file.exists()) { 
      if (file.mkdir()) { 
       System.out.println("Doctor is created!"); 
      } else { 
       System.out.println("Failed to create Doctor!"); 
      } 
     } 
     BufferedWriter out = new BufferedWriter(
     new FileWriter("C:\\Directroy111\\Digital Signature Doctor.txt")); 
     out.write(x); 
     out.close(); 
     this.copyImageFiles(sourceFile, destinationDir); 
     } 
      System.out.println("Message Digest Encrypted-1: "+hexString2.toString()+"\n"); 
    } 


public void firstVerify() throws IOException, NoSuchAlgorithmException, Throwable 
{ 
//Generate Message Digest1 - Decrypt 
String verifyfile= "c:\\Directroy111\\2.jpg"; 
File decryptfile= new File(verifyfile); 
byte[] buffer2=null; 
buffer2 = new byte[(int) decryptfile.length()]; //array type is integer, thats why we use int here 
FileInputStream fis2 = new FileInputStream(decryptfile); 
fis2.read(buffer2); 
MessageDigest messageDigest2 = MessageDigest.getInstance("SHA-256"); 
messageDigest2.update(buffer2); 
byte[] digestBytes2 = messageDigest2.digest(); 
StringBuffer hexString22 = new StringBuffer(); 
for(int i=0;i<digestBytes2.length;i++){ 
    hexString22.append(Integer.toHexString(0xFF & digestBytes2[i])); 
} 
System.out.println("Message Digest(Hash)-1(Decryption): "+hexString22.toString()); //System.out.println(hexString); 

    //*******Decypt*************// 
Signature signature = Signature.getInstance("SHA256withRSA"); 
    signature.initVerify(publicKey); 
    //FileReader read= new FileReader("C:\\TEMP1\\Doctor\\Digital Signature Doctor.txt"); 
    FileInputStream br2 = new FileInputStream("C:\\Directroy111\\Digital Signature Doctor.txt"); 
//BufferedInputStream bis=new BufferedInputStream(br2); 
    //BufferedReader br = new BufferedReader(new FileReader(br2)); 
    byte[] data2=new byte[br2.available()]; 
    System.out.println(Arrays.toString(data2)); 
    br2.read(data2); 
    br2.close(); 

    FileInputStream datafis=new FileInputStream("C:\\Directroy111\\Digital Signature Doctor.txt"); 
    BufferedInputStream bufin=new BufferedInputStream(datafis); 
    byte[] buffer=new byte[1024]; 

    int len; 
    while(bufin.available()!=0){ 
      len=bufin.read(buffer); 
      signature.update(buffer,0,len); 
     }; 
     bufin.close(); 
     System.out.println("111111"); 
     boolean decryptmd2= signature.verify(data2); 
     System.out.println("signature verifies: " + decryptmd2); 
     if(decryptmd2==false){ 
     str = String.valueOf(decryptmd2); 
     System.out.println("Message Digest-1(Decryption): "+str); 
     }else{ 
      System.out.println("1111"); 
     } 

      //**Verify* 
     if(str.equals(hexString22.toString())){ 
     System.out.println("Digital Signature-1 was not modified"+"\n"); 
     }else{ 

     System.out.println("ERROR!!! Digital Signature-1 was modified"+"\n"); 
     } 

} 
+0

請添加您用於生成簽名的代碼。 – gtrig

+0

我只是添加生成簽名的代碼。 – user2141529

回答

0

我在這裏看到一對夫婦的問題。首先,實際的簽名代碼也應包含在您的問題中。無法看到簽名代碼,調試問題就更加困難。檢查您的簽名算法是否與您的驗證算法(SHA256withRSA)相同。

接下來,如果您使用的是SHA256withRSA算法,你並不需要計算消息摘要第一。該算法會爲您計算並簽名摘要。您只需傳入整個文件即可進行簽名。

在您的驗證步驟中,您更新與你說的是簽名相同的文件簽名的對象。這兩個文件都是Digital Signature Doctor.txt。您應該更新簽名對象與待簽名的文件,我相信您的示例是2.jpg。然後,當您調用verify()方法時,傳入簽名字節。

最後,你曲解的verify()返回值。它返回一個布爾值。它不會返回消息摘要或原始消息。當您的代碼確實爲String.valueOf(decryptmd2)時,該值將爲「false」或「true」。

我不確定你爲什麼試圖比較消息摘要。假設您發送的消息帶有由您信任的公鑰所對應的私鑰簽名的簽名。中頻verify()方法返回true,你可以肯定的是:

  • 的消息是由人簽署
  • 所收到的郵件是相同的簽署

這應該是消息足以滿足您的需求。

+0

嗨gtrig, 我的建議是同這個網站的接收器的這一形象: http://www.indicthreads.com/1480/what-are-digital-signatures-compute-and-verify-a-digital-signature -using-java/ – user2141529

+0

SHA256withRSA爲我做了消息摘要??我不明白,但我檢查了API,它沒有說它會爲我生成消息摘要。這就是爲什麼我試圖產生消息摘要。 – user2141529

+0

如果我更改了布爾值decryptmd2 = signature.verify(data2);'boolean decryptmd2 = signature.verify(encryptmd);'它生成「true」,並且沒有錯誤。 「data2」是在我用私鑰簽名並將此數字簽名放入txt文件後的消息摘要,而另一個「encryptmd」(我沒有將它放到txt文件中)僅將其放到變量中,但是我不知道爲什麼「數據2」不起作用。「data2」和「encrypmd」都有相同的字符串(我已打印出來檢查)。 – user2141529

0

呼應gtrig的評論,這裏是展示簽名生成和驗證,一個完整的例子:

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

public class RSASignatureExample { 

    private static int BUFSIZE = 8192; 
    private PrivateKey privateKey; 
    private PublicKey publicKey; 

    public RSASignatureExample() throws Exception { 
     KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); 
     kpg.initialize(1024); 
     KeyPair kp = kpg.generateKeyPair(); 
     privateKey = kp.getPrivate(); 
     publicKey = kp.getPublic(); 
    } 

    private static void processData(File f, Signature s) throws Exception { 
     BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f), BUFSIZE); 
     byte[] buf = new byte[BUFSIZE]; 
     int numRead; 
     while ((numRead = bis.read(buf)) > 0) { 
      s.update(buf, 0, numRead); 
     } 
     bis.close(); 
    } 

    public byte[] sign(File fileToSign) throws Exception { 
     Signature signature = Signature.getInstance("SHA256withRSA"); 
     signature.initSign(privateKey); 
     processData(fileToSign, signature); 
     return signature.sign(); 
    } 

    public boolean verify(File fileToVerify, byte[] signatureBytes) throws Exception { 
     Signature signature = Signature.getInstance("SHA256withRSA"); 
     signature.initVerify(publicKey); 
     processData(fileToVerify, signature); 
     return signature.verify(signatureBytes); 
    } 

    public static void main(String[] args) throws Exception { 
     RSASignatureExample example = new RSASignatureExample(); 
     File tempFile = File.createTempFile("rsa", null); 
     FileOutputStream fos = new FileOutputStream(tempFile); 
     fos.write("Hello World".getBytes("UTF-8")); 
     fos.close(); 

     // Sign the file 

     byte [] signatureBytes = example.sign(tempFile); 

     // Verify the signature 

     boolean isVerified = example.verify(tempFile, signatureBytes); 
     System.out.printf("Signature verified ?: %b", isVerified); 
    } 
}