2015-10-21 42 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

相关问题