Проверка подписи Bouncycastle ECDSA в порядке после подписания, но не выполняется при следующем запуске при перезагрузке открытого ключа, сообщения и подписи - PullRequest
0 голосов
/ 22 апреля 2019

Я проверяю проверку подписи надувного замка. Интересно, что он проверяет нормально после подписания, но при запуске нового экземпляра с открытым ключом, сообщение и подпись, если всегда происходит сбой. Я использую ту же самую процедуру проверки сразу после генерации подписи и следующего запуска, который является простым кодом Java. (Вся история может быть неактуальной, но я пытаюсь создать сертификат CA открытого ключа javacard и должен подписать полученный сертификат. Сразу после генерации сертификата и подписи проверка всегда проходит, но при запуске следующего экземпляр для проверки сертификата открытого ключа не удается.) Я хотел бы попросить обратной связи, если это случилось с кем-либо еще. Я в значительной степени предполагаю, что код правильный, так как он работает сразу после подписания. Если код все же требуется, я его почистю и опубликую, но это похоже на примеры кода, найденные в сети.

public class VerifyEccSignature {
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException {
    boolean verify;
    Provider prov=new BouncyCastleProvider();
    Signature ecdsaSign;
    Security.addProvider(prov);

    // Card Public Key
    byte[] pubKey = HexAdapter.toBin("04cd7a82795bf691232e409ebe10039be6167d15b07e19da0c417c830d4db8b9d8f6919113468a1f650125545cc0bca619ec3be88723889fb439b71dee3e1dbad3");

    // Certificate to sign ()
    byte[] cert=HexAdapter.toBin("48656C6C6F576F726C64");

    // Signature returned by chip
    byte[] sigBytes=HexAdapter.toBin("30450220459408F84F45A1F960C3260D8191083617C016ADC721E5162F667D8E01BAEBCD0221008BE3EFD1F09363653B699CA39174D265218911023DA0DCBD04C1F44228D5E5FD");

    try {            
        // Get rpivate key
        KeyFactory keyFactory = KeyFactory.getInstance("ECDSA",prov);
        PKCS8EncodedKeySpec spec=new PKCS8EncodedKeySpec(HexAdapter.toBin("308193020100301306072A8648CE3D020106082A8648CE3D0301070479307702010104200BF4B825E8B758853A49E01EAA45905E249B580421C7306A8EC85B4F4229675DA00A06082A8648CE3D030107A14403420004CD7A82795BF691232E409EBE10039BE6167D15B07E19DA0C417C830D4DB8B9D8F6919113468A1F650125545CC0BCA619EC3BE88723889FB439B71DEE3E1DBAD3"));
        PrivateKey priv = keyFactory.generatePrivate(spec);
        ecdsaSign = java.security.Signature.getInstance("SHA256withECDSA",prov);

        // Generate signature of first run
        byte[] cc="HelloWorld".getBytes();
        ecdsaSign.initSign(priv);
        ecdsaSign.update(cc);            
        byte[] signature=ecdsaSign.sign();
        System.out.println("data " + HexAdapter.toHex(cc));
        System.out.println("signature= "+HexAdapter.toHex(signature));

        // Convert it to export format required for Tachograph certificate
        byte[] rawSignature=VerifySignature.getRawSignature(signature);

        // Setup verifing class
        VerifySignature vv=new VerifySignature(prov);

        // Verify current run
        verify=vv.verify(pubKey, ByteBuffer.wrap(cc), rawSignature);
        System.out.println("cc verify signature. Result: "+verify);

        // Verify previous run whre signature is copied into cert from output of previous run
        verify=vv.verify(pubKey, ByteBuffer.wrap(cert), sigBytes);

        // Output information required for verification and to copy over to next run
        System.out.println("pubkey "+HexAdapter.toHex(pubKey));
        System.out.println("cert "+HexAdapter.toHex(cert));     
        System.out.println("sig "+HexAdapter.toHex(sigBytes));

    } catch (NoSuchAlgorithmException ex) {
        Logger.getLogger(TestCaSignerEcc.class.getName()).log(Level.SEVERE, null, ex);
    } catch (InvalidKeyException ex) {
        Logger.getLogger(VerifyEccSignature.class.getName()).log(Level.SEVERE, null, ex);
    } catch (SignatureException ex) {
        Logger.getLogger(VerifyEccSignature.class.getName()).log(Level.SEVERE, null, ex);
    } catch (Exception ex) {
        Logger.getLogger(VerifyEccSignature.class.getName()).log(Level.SEVERE, null, ex);
    }

}

}

Проверка:

public class VerifySignature {
Provider prov;
Signature ecdsaSign;

public VerifySignature(Provider prov) {
    this.prov = prov;
}

public boolean verify(byte[] pubKey, ByteBuffer plainCert, byte[] rawSignature){

    boolean verify=false;

    try {              
        ECPublicKey pp= decodeKey(prov,pubKey);

        ASN1EncodableVector v = new ASN1EncodableVector();
        v.add(/*r*/new ASN1Integer(new BigInteger(1, Arrays.copyOfRange(rawSignature,0,32))));
        v.add(/*s*/new ASN1Integer(new BigInteger(1, Arrays.copyOfRange(rawSignature,32,32*2))));
        byte[] sigDer = new DERSequence(v).getEncoded();
        System.out.println("v "+v);

        // Verify signature
        ecdsaSign = java.security.Signature.getInstance("SHA256withECDSA",prov);
        ecdsaSign.initVerify(pp);
        ecdsaSign.update(plainCert);
        verify = ecdsaSign.verify(sigDer);
        System.out.println(" - Singnature verified: "+verify);

    } catch (NoSuchAlgorithmException ex) {
        Logger.getLogger(TestCaSignerEcc.class.getName()).log(Level.SEVERE, null, ex);
    } catch (InvalidKeySpecException | SignatureException | InvalidKeyException | IOException ex) {
        Logger.getLogger(VerifyEccSignature.class.getName()).log(Level.SEVERE, null, ex);
    } catch (NoSuchProviderException ex) {
        Logger.getLogger(VerifySignature.class.getName()).log(Level.SEVERE, null, ex);
    }
    return verify;
}

public static ECPublicKey decodeKey(Provider prov, byte[] encoded) throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchProviderException{
    java.security.spec.ECPoint point = new java.security.spec.ECPoint(  new BigInteger(1, Arrays.copyOfRange(encoded,1,33)), 
                                                                        new BigInteger(1, Arrays.copyOfRange(encoded,33,65))
                                                                        );

    ECNamedCurveParameterSpec params = ECNamedCurveTable.getParameterSpec(/*"secp256r1""prime256v1*/"P-256");
    KeyFactory fact = KeyFactory.getInstance("ECDSA",prov);
    ECCurve curve = params.getCurve();
    java.security.spec.EllipticCurve ellipticCurve = EC5Util.convertCurve(curve, params.getSeed());

    java.security.spec.ECParameterSpec params2=EC5Util.convertSpec(ellipticCurve, params);
    java.security.spec.ECPublicKeySpec keySpec = new java.security.spec.ECPublicKeySpec(point,params2);
    ECPublicKey pubKey=(ECPublicKey) fact.generatePublic(keySpec);
    return pubKey;
}

private static ASN1Primitive toAsn1Primitive(byte[] data) throws Exception
{
    try (ByteArrayInputStream inStream = new ByteArrayInputStream(data);
            ASN1InputStream asnInputStream = new ASN1InputStream(inStream);) 
    {
        return asnInputStream.readObject();
    }
}

public static byte[] getRawSignature(byte[] signed)throws Exception{
        ASN1Primitive asn1 = toAsn1Primitive(signed);
        byte[] rawSignature=new byte[0x40];
        byte[] tt;
        int ptr=0;
        if (asn1 instanceof ASN1Sequence) {
            ASN1Sequence asn1Sequence = (ASN1Sequence) asn1;
            ASN1Encodable[] asn1Encodables = asn1Sequence.toArray();
            for (ASN1Encodable asn1Encodable : asn1Encodables) {
                ASN1Primitive asn1Primitive = asn1Encodable.toASN1Primitive();
                if (asn1Primitive instanceof ASN1Integer) {
                    ASN1Integer asn1Integer = (ASN1Integer) asn1Primitive;
                    BigInteger integer = asn1Integer.getValue();
                    tt=BigIntegers.asUnsignedByteArray(asn1Integer.getValue());
                    System.arraycopy(tt, 0, rawSignature, ptr,  0x20);
                    ptr+=0x20;
                }
            }
        }
    return rawSignature;
}

}

1 Ответ

0 голосов
/ 23 апреля 2019

Извините, что беспокою вас всех. Кажется, что я вводил подпись напрямую, вместо того, чтобы преобразовать ее в необработанный формат, прежде чем преобразовать ее обратно в ASN1 во время проверки. Мой недосмотр. Питер

...