2015-10-21 63 views
0

我有兩段代碼使用Java的「SHA256withRSA」Signature。一種方法是一個InputStream裝飾者,通過read()方法的字節更新簽名字節:爲什麼SHA256withRSA簽名在計算逐字節與全部一次時不同?

public class SigningInputStream extends InputStream { 
    // Removed for brevity: declaration of useful objects 

    @Override 
    public int read() throws IOException { 
     final int nextByte = source.read(); 
     try { 
      sign.update((byte) nextByte); 
     } catch (java.security.SignatureException e) { 
      throw new IOException("Unknown exception while signing file", e); 
     } 

     return nextByte; 
    } 

    // Removed for brevity 
} 

其他生成簽名一下子:

Signature sign = Signature.getInstance("SHA256withRSA"); 
sign.initSign(privateKey); 

sign.update(contents); 
byte[] signature = sign.sign(); 
return Base64.getEncoder().encodeToString(signature); 

這兩種方法給我不同的結果。我仍在閱讀spec(我發現鏈接到另一個SO問題),但我不認爲我完全理解它。爲什麼兩種簽名方法(逐字節比較一次)會產生不同的簽名?

+0

如果'INT nextByte'恰好是'-1',你必須避免做'sign.update((byte)nextByte)'。 – mkl

回答

1

您沒有顯示如何使用您的SigningInputStream。因此,讓我們假設它完全沒有任何重置地被讀取,例如像這樣:

SigningInputStream sigIS = new SigningInputStream(...); 
while (sigIS.read() != -1); 

在這種情況下,上面已經環路暗示了問題:如果沒有可用的字節,因爲流的末尾已到達,read返回值-1

因此,如果您final int nextByte = source.read()-1,你必須忽略這個值,因爲它不是流內容的一部分:

public int read() throws IOException 
{ 
    final int nextByte = source.read(); 
    if (nextByte != -1) 
    [ 
     try { 
      sign.update((byte) nextByte); 
     } catch (java.security.SignatureException e) { 
      throw new IOException("Unknown exception while signing file", e); 
     } 
    } 

    return nextByte; 
} 
+0

在這裏,我認爲我偶然發現了Sha256 + RSA算法的一個深黑色的角落,當時這只是一個愚蠢的新手錯誤。謝謝回答。 – MonkeyWithDarts

相關問題