1

好的,我想在 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