4.2 RSA數(shù)字簽名技術(shù)

數(shù)字簽名技術(shù) - RSA數(shù)字簽名技術(shù)

RSA算法不僅是非對稱加密算法,也是數(shù)字簽名算法中的主力軍,和MD、SHA系列算法結(jié)合,產(chǎn)生數(shù)字簽名算法。

算法系列

RSA數(shù)字簽名技術(shù)可以分為MD和SHA系列量大類,數(shù)字簽名技術(shù)本身就是信息摘要和非對稱加密技術(shù)的結(jié)合。

  • MD系列包括:MD2withRSA、MD5withRSA
  • SHA系列包括:SHA1withRSASHA224withRSA、SHA256withRSASHA384withRSA、SHA512withRSA五種。

這些算法的密鑰長度都在512-65535位之間,必須是64的倍數(shù)。產(chǎn)生的簽名長度和密鑰長度一致。

算法基本過程

  • 將數(shù)據(jù)使用摘要算法計算摘要(hash值);
  • 使用私鑰摘要進行加密;
  • 將加密數(shù)據(jù)和原始數(shù)據(jù)一起傳輸;
  • 接收方對原始數(shù)據(jù)(要保持原始數(shù)據(jù)的序列一致性,約定好)計算摘要;
  • 使用公鑰解密簽名串,比較二者Hash值是否一致;

Java中的算法實現(xiàn)

Java中不僅僅實現(xiàn)了RSA算法,還實現(xiàn)了RSA數(shù)字簽名算法,JDK僅提供了MD2withRSA、MD5withRSASHA1withRSA三種數(shù)字簽名算法。

JDK中對三種算法的默認密鑰長度為1024

示例代碼:

public class SignatureTest {

    public static final String SIGN_ALGORITHM = "MD5withRSA";
    private static final String KEY_ALGORITHM = "RSA";
    private static final int KEY_SIZE = 512;

    public static void main(String[] args) throws Exception {
        KeyPair keyPair = initKey();
        String input = "Sign Me";
        
        byte[] sign = sign(input.getBytes(), keyPair.getPrivate().getEncoded());
        boolean verify = verify(input.getBytes(), sign, keyPair.getPublic().getEncoded());

        String msg = String.format("原始數(shù)據(jù): %s , Sign : %s , Verify : %s", input, toBase64(sign), verify);
        System.out.println(msg);
        // 從二進制位角度看,sign的長度和密鑰長度一致
        System.out.println("Sign Size : " + (sign.length * 8) + " Key Size : " + KEY_SIZE);
    }

    public static KeyPair initKey() throws Exception {
        KeyPairGenerator keyPairGr = KeyPairGenerator.getInstance(KEY_ALGORITHM);
        keyPairGr.initialize(KEY_SIZE);
        KeyPair keyPair = keyPairGr.generateKeyPair();
        return keyPair;
    }

    public static byte[] sign(byte[] data, byte[] privateKey) throws Exception {
        // 將byte[]的key格式化回來
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKey);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
        // 獲取算法實例并初始化
        Signature signature = Signature.getInstance(SIGN_ALGORITHM);
        signature.initSign(priKey);
        signature.update(data);
        byte[] sign = signature.sign();
        return sign;
    }

    public static boolean verify(byte[] data, byte[] sign, byte[] publicKey) throws Exception {
        // 獲取算法實例并初始化
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(publicKey);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PublicKey pubKey = keyFactory.generatePublic(x509KeySpec);
        Signature signature = Signature.getInstance(SIGN_ALGORITHM);
        signature.initVerify(pubKey);
        signature.update(data);
        // 驗證數(shù)據(jù)和簽名是否一致,放否認,放篡改
        boolean verify = signature.verify(sign);
        return verify;
    }

    public static String toBase64(byte[] data) {
        return new String(Base64.getEncoder().encode(data));
    }

}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容