Java实现数字签名

  • 数字签名 - 带有密钥(公钥、私钥)的消息摘要算法
  • 验证数据的完整性、认证数据来源、抗否认
  • OSI参考模型
  • 私钥签名、公钥验证
  • RSA、DSA、ECDSA

数字签名算法 - RSA

  • 经典算法
  • MD、SHA两类
密钥长度 默认 工作模式 填充方式 实现方
MD2withRSA 512~65536(64的整数倍) 1024 与密钥长度相同 JDK
MD5withRSA JDK
SHA1withRSA JDK
SHA224withRSA 2048 BC
SHA256withRSA BC
SHA384withRSA BC
SHA512withRSA BC
RIPEMD128withRSA BC
RIPEMD160withRSA BC
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import org.apache.commons.codec.binary.Hex;

import com.sun.xml.internal.fastinfoset.algorithm.HexadecimalEncodingAlgorithm;



public class RSATest{

    public static final String src = "RSA security is security";
    
    public static void main(String[] args) {
        jdkRSA();
    }
    
    /**
     * @author timliu
     * 说明: 用java的jdk里面相关方法实现rsa的签名及签名验证
     */
    public static void jdkRSA(){
        try {
            // 1.初始化密钥
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(512);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            RSAPublicKey rsaPublicKey = (RSAPublicKey)keyPair.getPublic();
            RSAPrivateKey rsaPrivateKey = (RSAPrivateKey)keyPair.getPrivate();
            
            // 2.进行签名
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            Signature signature = Signature.getInstance("MD5withRSA");
            signature.initSign(privateKey);
            signature.update(src.getBytes());
            byte[] result = signature.sign();
            System.out.println("jdk rsa sign:" + Hex.encodeHexString(result) );
            
            // 3.验证签名
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
            keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            signature = Signature.getInstance("MD5withRSA");
            signature.initVerify(publicKey);
            signature.update(src.getBytes());
            boolean bool = signature.verify(result);
            System.out.println("jdk rsa verify:" + bool);
        } catch (Exception e) {
            System.out.println(e.toString());
        }
    }
}
Java实现数字签名_第1张图片
数字签名算法 - RSA

数字签名算法 - DSA

  • DSS(Digital Signature Standard)数字签名标准
  • DSA(Digital Signature Algorithm)数字签名算法
  • DSA 仅含数字签名(无法进行加密通讯)
密钥长度 默认 工作模式 实现方
SHA1withRSA 512~1024(64的整数倍) 1024 JDK
SHA224withRSA BC
SHA256withRSA BC
SHA384withRSA BC
SHA512withRSA BC
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.DSAPrivateKey;
import java.security.interfaces.DSAPublicKey;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import org.apache.commons.codec.binary.Hex;

import com.sun.xml.internal.fastinfoset.algorithm.HexadecimalEncodingAlgorithm;



public class DSATest{

    public static final String src = "DSA security is security";
    
    public static void main(String[] args) {
        jdkDSA();
    }
    
    /**
     * 
     * @author timliu
     * 说明: 用java的jdk里面相关方法实现dsa的签名及签名验证
     */
    public static void jdkDSA(){
        try {
            // 1.初始化密钥
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DSA");
            keyPairGenerator.initialize(512);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            DSAPublicKey dsaPublicKey = (DSAPublicKey)keyPair.getPublic();
            DSAPrivateKey dsaPrivateKey = (DSAPrivateKey)keyPair.getPrivate();
            
            // 2.进行签名
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(dsaPrivateKey.getEncoded());
            KeyFactory keyFactory = KeyFactory.getInstance("DSA");
            PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            Signature signature = Signature.getInstance("SHA1withDSA");
            signature.initSign(privateKey);
            signature.update(src.getBytes());
            byte[] result = signature.sign();
            System.out.println("jdk dsa sign:" + Hex.encodeHexString(result) );
            
            // 3.验证签名
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(dsaPublicKey.getEncoded());
            keyFactory = KeyFactory.getInstance("DSA");
            PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            signature = Signature.getInstance("SHA1withDSA");
            signature.initVerify(publicKey);
            signature.update(src.getBytes());
            boolean bool = signature.verify(result);
            System.out.println("jdk dsa verify:" + bool);
        } catch (Exception e) {
            System.out.println(e.toString());
        }
    }
}
Java实现数字签名_第2张图片
数字签名算法 - DSA

数字签名算法 - ECDSA

  • 微软序列号
  • Elliptic Curve Digital Signature Algorithm,椭圆曲线数据签名算法
  • 速度快、强度高、签名短
算法 密钥长度 默认 签名长度 实现方
NONEwithECDSA 112~571 256 JDK/BC
RIPEMD160withECDSA BC
SHA1withECDSA JDK/BC
SHA224withECDSA BC
SHA256withECDSA JDK/BC
SHA384withECDSA JDK/BC
SHA512withECDSA JDK/BC
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.DSAPrivateKey;
import java.security.interfaces.DSAPublicKey;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import org.apache.commons.codec.binary.Hex;

import com.sun.xml.internal.fastinfoset.algorithm.HexadecimalEncodingAlgorithm;

public class ECDSATest{
    public static final String src = "ECDSA security is security";
    
    public static void main(String[] args) {
        jdkECDSA();
    }
    
    /**
     * @author timliu
     * 说明: 用java的jdk里面相关方法实现ECDSA的签名及签名验证,要jdk7.x以上,ECDSA:椭圆曲线数字签名算法
     */
    public static void jdkECDSA(){
        try {
            // 1.初始化密钥
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC");
            keyPairGenerator.initialize(256);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            ECPublicKey ecPublicKey = (ECPublicKey)keyPair.getPublic();
            ECPrivateKey ecPrivateKey = (ECPrivateKey)keyPair.getPrivate();
            
            // 2.进行签名
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(ecPrivateKey.getEncoded());
            KeyFactory keyFactory = KeyFactory.getInstance("EC");
            PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            Signature signature = Signature.getInstance("SHA1withECDSA");
            signature.initSign(privateKey);
            signature.update(src.getBytes());
            byte[] result = signature.sign();
            System.out.println("jdk ecdsa sign:" + Hex.encodeHexString(result) );
            
            // 3.验证签名
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(ecPublicKey.getEncoded());
            keyFactory = KeyFactory.getInstance("EC");
            PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            signature = Signature.getInstance("SHA1withECDSA");
            signature.initVerify(publicKey);
            signature.update(src.getBytes());
            boolean bool = signature.verify(result);
            System.out.println("jdk ecdsa verify:" + bool);
        } catch (Exception e) {
            System.out.println(e.toString());
        }
    }
}
Java实现数字签名_第3张图片
数字签名算法 - ECDSA

你可能感兴趣的:(Java实现数字签名)