1

OK、Python で ecdsa を使用して署名し、Java で検証したいと思います。これを行うために、m2crypto を使用した短い Python スクリプトと、Bouncycastle を使用した短い Java アプリケーションを開発しました。

Pythonでキーを生成し、PythonでサインインしてPythonで検証すると機能し、Javaでキーを生成し、JavaでサインインしてJavaで検証すると機能しますが、キーを共有しようとすると、すべてが少し梨になります-成形。- Java から Python へ、またはその逆方向に共有できませんでした。

以下、実行するとJavaの最後に到達し、「チェックに失敗しました」で「失敗」するという点で機能するはずですが、コードにエラーが見つかりません。おそらく本当に単純な/明白なバグだと確信しています:

1) 鍵の生成(python、m2crypt):

from M2Crypto import EC
key = EC.gen_params(EC.NID_secp112r2) # Picked a random NID...
key.gen_key()
key.save_key("ecpriv.pem", None)
key.save_pub_key("ecpub.pem")

2) 署名(python、m2crypt):

def bigint(string):
    return int(string.encode('hex'), 16)

myhash = "hello" # Yes, this should be a sha1 of something but shouldn't matter?
key = EC.load_key('ecpriv.pem')
sigr, sigs = key.sign_dsa(myhash)

intr = bigint(sigr)
ints = bigint(sigs)

print (intr, ints)

「bigint」の使用は、m2crypt から返されたバイナリ文字列から、弾む城が必要とする大きな整数に変換することです。それをコピーしてアプリケーションに貼り付けます。

3) 検証(java、bouncycastle):

import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.signers.ECDSASigner;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.util.PublicKeyFactory;
import org.bouncycastle.util.io.pem.PemReader;
import org.bouncycastle.util.io.pem.PemObject;
import java.math.BigInteger;
import java.io.FileReader; 

class ECVerify {
    public static void main(String[] args) {
        System.out.println("EC Verification"); // Display the string.

        String strmessage = "";
        String sigr = "";
        String sigs = "";

        try {
            strmessage = args[0];
            sigr = args[1];
            sigs = args[2];
        } catch (Exception e) {
            System.out.println("Bad Argument?");
            System.out.println(e.toString());

            System.out.println("java ECVerify message r s");
            return;
        }

        try {
            PemReader reader = new PemReader(new FileReader("ecpub.pem"));
            PemObject poKey = (PemObject) reader.readPemObject();

            byte[] poContent = poKey.getContent();

            // Now we have a signature we have to try and verify       
            ECDSASigner mySignValidator = new ECDSASigner();

            ECPublicKeyParameters myPublicKey = (ECPublicKeyParameters) PublicKeyFactory.createKey(poContent);

            // From here down its all ok *I think*
            mySignValidator.init(false, myPublicKey);

            byte[] message = strmessage.getBytes();

            System.out.println("Message: " + byteArrToHexStr(message));
            System.out.println("Message: " + new BigInteger(sigr).toString() +" " +  new BigInteger(sigs).toString());

            boolean check = mySignValidator.verifySignature(message, new BigInteger(sigr), new BigInteger(sigs));

            if(check) {
                System.out.println("Check passed");
            } else {
                System.out.println("Check failed");
            }

        } catch (Exception e) {
            System.out.println("Error in main:");
            System.out.println(e.toString());
        }
    }

    // What follows are just convenience functions for printing

    public static String byteAsHexString ( byte b )
        {
                String rV = "";

                int k = (int) b;
                k = k & 0xff;            
                if ( k <= 0xf )
                {                
                        rV = rV + "0";
                }
                rV = rV + Integer.toHexString ( k );
                return rV;
        }

    public static String byteArrToHexStr ( byte[] bs )
        {
                StringBuffer sb = new StringBuffer();
                for(int i=0; i< bs.length; i++)
                {
                        sb.append( byteAsHexString ( bs[i] ));

                }
                return sb.toString();
        }

    public static byte[] hexStrToByte(String hex) {
        // look for sepeartor

        StringBuffer tempBuf = new StringBuffer(hex);

        for (int i=0; i<tempBuf.length(); i++) {
            char c = tempBuf.charAt(i);  
            if (!((c >= 'A' && c <= 'F')|| (c >= 'a' && c <= 'f')|| (c >= '0' && c <= '9'))) {
                tempBuf.deleteCharAt(i);
                 i--;
            }
        }

        hex = tempBuf.toString();

        byte[] bts = new byte[hex.length() / 2];
        for (int i = 0; i < bts.length; i++) {
            bts[i] = (byte) Integer.parseInt(hex.substring(2*i, 2*i+2), 16);
        }

        return bts;
    }

}

ありがとう!

4

0 に答える 0