ECDSA算法的教程签署串

问题描述 投票:14回答:2

你能不能帮我找到如何登录Java中使用ECDSA算法的字符串一个简单的教程。但不使用任何第三方库像BouncyCastle的。只是JDK 7,我发现很难寻找一个简单的例子,我是新来加密。


import java.io.*;
import java.security.*;

public class GenSig {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        /*
         * Generate a DSA signature
         */

        try {

            /*
             * Generate a key pair
             */

            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", "SUN");
            SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");

            keyGen.initialize(1024, random);

            KeyPair pair = keyGen.generateKeyPair();
            PrivateKey priv = pair.getPrivate();
            PublicKey pub = pair.getPublic();

            /*
             * Create a Signature object and initialize it with the private key
             */

            Signature dsa = Signature.getInstance("SHA1withDSA", "SUN");

            dsa.initSign(priv);

            String str = "This is string to sign";
            byte[] strByte = str.getBytes();
            dsa.update(strByte);

            /*
             * Now that all the data to be signed has been read in, generate a
             * signature for it
             */

            byte[] realSig = dsa.sign();
            System.out.println("Signature: " + new String(realSig));


        } catch (Exception e) {
            System.err.println("Caught exception " + e.toString());
        }
    }
}

如何修改它ECDSA?

java cryptography digital-signature bouncycastle
2个回答
19
投票

这是根据您的例子小例子。

注:这是这个答案的原代码,请参见下面的代码片段为一个更新的版本。

import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;

public class ECDSAExample {

    public static void main(String[] args) throws Exception {
        /*
         * Generate an ECDSA signature
         */

        /*
         * Generate a key pair
         */

        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
        SecureRandom random = SecureRandom.getInstance("SHA1PRNG");

        keyGen.initialize(256, random);

        KeyPair pair = keyGen.generateKeyPair();
        PrivateKey priv = pair.getPrivate();
        PublicKey pub = pair.getPublic();

        /*
         * Create a Signature object and initialize it with the private key
         */

        Signature dsa = Signature.getInstance("SHA1withECDSA");

        dsa.initSign(priv);

        String str = "This is string to sign";
        byte[] strByte = str.getBytes("UTF-8");
        dsa.update(strByte);

        /*
         * Now that all the data to be signed has been read in, generate a
         * signature for it
         */

        byte[] realSig = dsa.sign();
        System.out.println("Signature: " + new BigInteger(1, realSig).toString(16));

    }
}

UPDATE:这里是略微改进的实施例中除去弃用算法。在RFC 8422.规定还明确要求使用SECG符号“secp256r1”的NIST P-256曲线

import javax.xml.bind.DatatypeConverter;
import java.security.*;
import java.security.spec.ECGenParameterSpec;

public class ECDSAExample {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws Exception {
        /*
         * Generate an ECDSA signature
         */

        /*
         * Generate a key pair
         */

        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");

        keyGen.initialize(new ECGenParameterSpec("secp256r1"), new SecureRandom());

        KeyPair pair = keyGen.generateKeyPair();
        PrivateKey priv = pair.getPrivate();
        PublicKey pub = pair.getPublic();

        /*
         * Create a Signature object and initialize it with the private key
         */

        Signature ecdsa = Signature.getInstance("SHA256withECDSA");

        ecdsa.initSign(priv);

        String str = "This is string to sign";
        byte[] strByte = str.getBytes("UTF-8");
        ecdsa.update(strByte);

        /*
         * Now that all the data to be signed has been read in, generate a
         * signature for it
         */

        byte[] realSig = ecdsa.sign();
        System.out.println("Signature: " + DatatypeConverter.printHexBinary(realSig));

    }
}

1
投票
class ECCCipher {
    @Override
    public byte[] sign(PrivateKey privateKey, String message) throws Exception {
        Signature signature = Signature.getInstance("SHA1withECDSA");
        signature.initSign(privateKey);

        signature.update(message.getBytes());

        return signature.sign();
    }

    @Override
    public boolean verify(PublicKey publicKey, byte[] signed, String message) throws Exception {
        Signature signature = Signature.getInstance("SHA1withECDSA");
        signature.initVerify(publicKey);

        signature.update(message.getBytes());

        return signature.verify(signed);
    }
}

========================

public class ECCCipherTest {

private final KeyPairGenerator keygen;

public ECCCipherTest() throws NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException {
    Security.addProvider(new BouncyCastleProvider());
    this.keygen = KeyPairGenerator.getInstance("ECDSA", "BC");
    keygen.initialize(new ECGenParameterSpec("brainpoolP384r1"));
}

@Test
public void ECC_CipherTest_1() throws Exception {
    String message = "hello world";

    ICipher<PrivateKey, PublicKey> cipher = new ECCCipher();
    KeyPair keyPair = keygen.generateKeyPair();

    byte[] encrypted = cipher.sign(keyPair.getPrivate(), message);

    Assert.assertTrue(cipher.verify(keyPair.getPublic(), encrypted, message));
}

}

这是从我的项目一小段代码。这个对我有用。我已经包含了一个JUnit测试为好;希望这可以帮助。

以防万一有人想知道我们如何加载私钥和PUBKEY:(注意:是的privKey代表Java中的BigInteger的字节数组,而PUBKEY是二进制格式的曲线点)

    @Override
public PrivateKey generatePrivateKey(byte[] keyBin) throws InvalidKeySpecException, NoSuchAlgorithmException {
    ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("secp256k1");
    KeyFactory kf = KeyFactory.getInstance("ECDSA", new BouncyCastleProvider());
    ECNamedCurveSpec params = new ECNamedCurveSpec("secp256k1", spec.getCurve(), spec.getG(), spec.getN());
    ECPrivateKeySpec privKeySpec = new ECPrivateKeySpec(new BigInteger(keyBin), params);
    return kf.generatePrivate(privKeySpec);
}

@Override
public PublicKey generatePublicKey(byte[] keyBin) throws InvalidKeySpecException, NoSuchAlgorithmException {
    ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("secp256k1");
    KeyFactory kf = KeyFactory.getInstance("ECDSA", new BouncyCastleProvider());
    ECNamedCurveSpec params = new ECNamedCurveSpec("secp256k1", spec.getCurve(), spec.getG(), spec.getN());
    ECPoint point =  ECPointUtil.decodePoint(params.getCurve(), keyBin);
    ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(point, params);
    return kf.generatePublic(pubKeySpec);
}
© www.soinside.com 2019 - 2024. All rights reserved.