2017-01-02 7 views
1

とのOpenSSLによって署名された文字列を確認することができないCreating a DSA Signature from the Linux command lineで方向を適応Iは、DSA署名されたメッセージ作成:実際foo.sha1代わりfoo.txtのの使用DSAキー

echo "foobar" > foo.txt 
openssl dgst -dss1 -sign dsa_priv.pem foo.txt > sigfile.bin 

方向、foo.sha1ありましたsha1sumによって生成されますが、DSA自体がハッシュを行うため、ハッシュに署名することは少し冗長であるようです。

とにかく、私はそれをしました。ここで私が使用した秘密鍵は(私はテスト目的のために特別に生成された)です:

-----BEGIN DSA PRIVATE KEY----- 
MIIBvAIBAAKBgQDsGAHAM16bsPlwl7jaec4QMynYa0YLiLiOZC4mvH4UW/tRJxTz 
aV7eH1EtnP9D9J78x/07wKYs8zJEWCXmuq0UluQfjA47+pb68b/ucQTNeZHboNN9 
5oEi+8BCSK0y8G3uf3Y89qHvqa9Si6rP374MinEMrbVFm+UpsGflFcd83wIVALtJ 
ANi+lYG7xMKQ/bE4+bS8gemNAoGBAORowvirD7AB9x2SpdiME41+O4jVR8rs6+GX 
Ml3Hif6Yt1kem0CeraX9SNoyBNAzjD5TVMGIdGlgRr6GNreHeXMGWlvdDkvCACER 
ZEEtMsKZicm+yl6kR8AGHTCA/PBltHfyrFQd4n9I//UDqI4RjqzvpCXGQcVEsSDY 
CCBGBQJRAoGBALnHTAZlpoLJZuSBVtnMuRM3cSX43IkE9w9FveDV1jX5mmfK7yBV 
pQFV8eVJfk91ERQ4Dn6ePLUv2dRIt4a0S0qHqadgzyoFyqkmmUi1kNLyixtRqh+m 
2gXx0t63HEpZDbEPppdpnlppZquVQh7TyrKSXW9MTzUkQjFI9UY7kZeKAhQXiJgI 
kBniZHdFBAZBTE14YJUBkw== 
-----END DSA PRIVATE KEY----- 

ここsigfile.binの進エンコードされた出力です:

302c021456d7e7da10d1538a6cd45dcb2b0ce15c28bac03402147e973a4de1e92e8a87ed5218c797952a3f854df5 

私は今はBouncyCastleとJavaでこれを確認しようとしていますそうすることができません。私のJavaコードは次のとおりです。

import java.io.StringReader; 
import org.bouncycastle.openssl.PEMReader; 
import java.security.interfaces.DSAPublicKey; 
import org.bouncycastle.crypto.params.DSAPublicKeyParameters; 

import org.bouncycastle.crypto.signers.DSADigestSigner; 
import org.bouncycastle.crypto.signers.DSASigner; 
import org.bouncycastle.crypto.digests.SHA1Digest; 
import org.bouncycastle.crypto.params.DSAParameters; 

public class DSA 
{ 
    public static void main(String[] args) 
    throws Exception 
    { 
     byte[] message = "foobar".getBytes(); 
     byte[] signature = hexStringToByteArray("302c021456d7e7da10d1538a6cd45dcb2b0ce15c28bac03402147e973a4de1e92e8a87ed5218c797952a3f854df5"); 

      String key = "-----BEGIN PUBLIC KEY-----\n" + 
       "MIIBuDCCASwGByqGSM44BAEwggEfAoGBAOwYAcAzXpuw+XCXuNp5zhAzKdhrRguI\n" + 
       "uI5kLia8fhRb+1EnFPNpXt4fUS2c/0P0nvzH/TvApizzMkRYJea6rRSW5B+MDjv6\n" + 
       "lvrxv+5xBM15kdug033mgSL7wEJIrTLwbe5/djz2oe+pr1KLqs/fvgyKcQyttUWb\n" + 
       "5SmwZ+UVx3zfAhUAu0kA2L6VgbvEwpD9sTj5tLyB6Y0CgYEA5GjC+KsPsAH3HZKl\n" + 
       "2IwTjX47iNVHyuzr4ZcyXceJ/pi3WR6bQJ6tpf1I2jIE0DOMPlNUwYh0aWBGvoY2\n" + 
       "t4d5cwZaW90OS8IAIRFkQS0ywpmJyb7KXqRHwAYdMID88GW0d/KsVB3if0j/9QOo\n" + 
       "jhGOrO+kJcZBxUSxINgIIEYFAlEDgYUAAoGBALnHTAZlpoLJZuSBVtnMuRM3cSX4\n" + 
       "3IkE9w9FveDV1jX5mmfK7yBVpQFV8eVJfk91ERQ4Dn6ePLUv2dRIt4a0S0qHqadg\n" + 
       "zyoFyqkmmUi1kNLyixtRqh+m2gXx0t63HEpZDbEPppdpnlppZquVQh7TyrKSXW9M\n" + 
       "TzUkQjFI9UY7kZeK\n" + 
       "-----END PUBLIC KEY-----"; 
     PEMReader reader = new PEMReader(new StringReader(key)); 
     DSAPublicKey decoded = (DSAPublicKey) reader.readObject(); 

     DSADigestSigner dsa = new DSADigestSigner(new DSASigner(), new SHA1Digest()); 
     DSAParameters params = new DSAParameters(
      decoded.getParams().getP(), 
      decoded.getParams().getQ(), 
      decoded.getParams().getG() 
     ); 
     DSAPublicKeyParameters publickey = new DSAPublicKeyParameters(decoded.getY(), params); 
     dsa.init(false, publickey); 
     dsa.update(message, 0, message.length); 
     boolean result = dsa.verifySignature(signature); 

     System.out.println(result ? "good" : "bad"); 
    } 

    public static byte[] hexStringToByteArray(String s) 
    { 
     int len = s.length(); 
     byte[] data = new byte[len/2]; 
     for (int i = 0; i < len; i += 2) 
     { 
      data[i/2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) 
       + Character.digit(s.charAt(i+1), 16)); 
     } 
     return data; 
    } 
} 

署名が検証されていません。私のJavaコードに何か問題がありますか?たぶんOpenSSLはdss1で変なことをしているのでしょうか?

Iは、OpenSSLとうまく署名を検証することができた:

openssl dgst -dss1 -verify dsa_pub.pem -signature sigfile.bin foo.txt 

答えて

2

をスペースで区切られた複数の、PLUS NEWLINE場合(UNIX)echoは、その引数を出力します。検証するデータとして"foobar\n"を使用してください。あるいは、printf '%s' foobar >foo.txtの結果に署名してください。移植可能なは改行を省略しています。 一部のバージョンechoのサポート-nこの目的のために、古いものは\cを使用しているものもあれば、まったくサポートしていないものもあります。

FYI BouncyCastleバージョン150(2013)以降は、もはやorg.bouncycastle.openssl.PEMReaderを持っていません。代わりにが返され、org.bouncycastle.asn1.x509.SubjectPublicKeyInfoが返され、org.bouncycastle.openssl.jcajce.JcaPEMKeyConverterまたはKeyFactory.getInstance(alg).generatePublicKey(new X509EncodedKey(spki.getEncoded()))でキーオブジェクトに変換することができます。これはJcaPEMKeyConverterが実際に行うものです。

OTOH org.bouncycastle.jcajce.provider.asymmetric.dsa.DSAUtil.generatePublicKeyParameterを使用して、その手札をパラメータピースに置き換えることができます。 BCプロバイダのインターフェース(軽量インターフェースとは対照的に)がそうです。もちろん、最初はJCAを使うだけで、OpenSSLのpublickey形式(プライベートキーと違って)は基本的なJava暗号と一貫して互換性があるので、BCは本当に必要ありません。

また、BTW openssl dgstには、バージョン0.9.8までの-dss1ハックが必要でした。バージョン1.0.0がリリースされて以来(ただし、実際のまたは互換性のために多くのディストリビューションや製品によってすぐにアップグレードされるわけではありません)、-sha1とDSA pubkeyが必要です。

関連する問題