ECDSA算法教程对字符串进行签名

use*_*574 15 java cryptography bouncycastle digital-signature

你能帮我找一个简单的教程,讲解如何在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());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如何修改ECDSA?

Jam*_*olk 20

以下是基于您的示例的小示例.

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));

    }
}
Run Code Online (Sandbox Code Playgroud)

  • 在调试器中运行它并作弊有点揭示:secp256r1 [NIST P-256,X9.62 prime256v1] (3认同)
  • 我担心有人会问这个问题.我不知道,P-256会是我的猜测. (2认同)

lin*_*hrr 7

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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));
}
Run Code Online (Sandbox Code Playgroud)

}

这是我的项目中的一个小代码片段。这个对我有用。我还包含了一项 junit 测试;希望这有帮助。

以防万一有人想知道我们如何加载私钥和公钥:(注意: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);
}
Run Code Online (Sandbox Code Playgroud)