已掉线,重新登录

首页 > 绿虎论坛 > 历史版块 > 编程 > Java

标题: 对文本或文件进行数字签名

作者: @Ta

时间: 2022-08-25发布,2022-08-27修改

点击: 1001

对文本或文件进行数字签名。

Kotlin 代码:

代码区域可编辑,点击右上角可运行,运行结果在代码底部。

网页链接

公钥、私钥和签名内容均以 Base64 编码为字符串。

SignatureToolbox 中的方法:

  • createKeyPair()
    新建一对公钥和私钥并返回。
  • signText()/signFile()
    使用私钥,对文本/文件进行数字签名,并返回签名内容。
  • verifyTextSign()/verifyFileSign()
    使用公钥和签名,验证文本/文件的内容是否正确并返回结果。

密钥算法是 DSA ,长度 2048,签名算法是 SHA256withDSA。编辑代码中的这些常量可以变更算法。


[隐藏样式|查看源码]


『回复列表(2|隐藏机器人聊天)』

1. @ChatGPT,尝试将下面的Kotlin代码转化为Java代码:
import java.io.BufferedInputStream
import java.io.FileInputStream
import java.security.KeyFactory
import java.security.KeyPair
import java.security.KeyPairGenerator
import java.security.Signature
import java.security.spec.PKCS8EncodedKeySpec
import java.security.spec.X509EncodedKeySpec
import java.util.Base64

fun main() {
    with(SignatureToolbox) {
        val keyPair = createKeyPair()
        val publicKey = keyPair.publicKey
        val privateKey = keyPair.privateKey
        println("New key pair created.")
        println("Public key: $publicKey")
        println("Private key: $privateKey")
        val textToSign = "这里是要被数字签名的文字。"
        println("Text to sign: $textToSign")
        val signature = signText(textToSign, privateKey)
        println("Signature: $signature")
        println("Verify signature: ${verifyTextSign(textToSign, publicKey, signature)}")
    }
}

object SignatureToolbox {
    private const val KEY_PAIR_GENERATOR_ALGORITHM = "DSA"
    private const val KEY_SIZE = 2048
    private const val SIGNATURE_ALGORITHM = "SHA256withDSA"

    private const val FILE_BUFFER_SIZE = 4096

    data class KeyPairBase64(val publicKey: String, val privateKey: String) {
        constructor(keyPair: KeyPair) : this(keyPair.public.encoded.toBase64(), keyPair.private.encoded.toBase64())
    }
    
    fun createKeyPair() =
        with(KeyPairGenerator.getInstance(KEY_PAIR_GENERATOR_ALGORITHM)) {
            initialize(KEY_SIZE)
            KeyPairBase64(generateKeyPair())
        }

    fun signText(text: String, privateKeyBase64: String) =
        with(Signature.getInstance(SIGNATURE_ALGORITHM)) {
            initSign(privateKeyBase64.base64ToPrivateKey())
            update(text.toByteArray())
            sign().toBase64()
        }

    fun signFile(filePath: String, privateKeyBase64: String) =
        with(Signature.getInstance(SIGNATURE_ALGORITHM)) {
            initSign(privateKeyBase64.base64ToPrivateKey())
            val bufferedInputStream = BufferedInputStream(FileInputStream(filePath))
            val buffer = ByteArray(FILE_BUFFER_SIZE)
            var len: Int
            while (bufferedInputStream.read(buffer).also { len = it } >= 0) {
                update(buffer, 0, len)
            }
            bufferedInputStream.close()
            sign().toBase64()
        }

    fun verifyTextSign(text: String, publicKeyBase64: String, signatureBase64: String) =
        with(Signature.getInstance(SIGNATURE_ALGORITHM)) {
            initVerify(publicKeyBase64.base64ToPublicKey())
            update(text.toByteArray())
            verify(signatureBase64.base64ToByteArray())
        }

    fun verifyFileSign(filePath: String, publicKeyBase64: String, signatureBase64: String) =
        with(Signature.getInstance(SIGNATURE_ALGORITHM)) {
            initVerify(publicKeyBase64.base64ToPublicKey())
            val bufferedInputStream = BufferedInputStream(FileInputStream(filePath))
            val buffer = ByteArray(FILE_BUFFER_SIZE)
            var len: Int
            while (bufferedInputStream.available() != 0) {
                len = bufferedInputStream.read(buffer)
                update(buffer, 0, len)
            }
            bufferedInputStream.close()
            verify(signatureBase64.base64ToByteArray())
        }

    private fun String.base64ToPublicKey() =
        KeyFactory.getInstance(KEY_PAIR_GENERATOR_ALGORITHM)
            .generatePublic(X509EncodedKeySpec(this.base64ToByteArray()))

    private fun String.base64ToPrivateKey() =
        KeyFactory.getInstance(KEY_PAIR_GENERATOR_ALGORITHM)
            .generatePrivate(PKCS8EncodedKeySpec(this.base64ToByteArray()))

    private fun String.base64ToByteArray() = Base64.getDecoder().decode(this)!!

    private fun ByteArray.toBase64() = Base64.getEncoder().encodeToString(this)!!
}
(/@Ta/2023-05-13 01:03//)

2.

@tasy5kg,以下是将给定的Kotlin代码转换为Java代码后的结果:

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

public class Main {
    private static final String KEY_PAIR_GENERATOR_ALGORITHM = "DSA";
    private static final int KEY_SIZE = 2048;
    private static final String SIGNATURE_ALGORITHM = "SHA256withDSA";
    private static final int FILE_BUFFER_SIZE = 4096;

    public static void main(String[] args) {
        SignatureToolbox signatureToolbox = SignatureToolbox.getInstance();
        SignatureToolbox.KeyPairBase64 keyPair = signatureToolbox.createKeyPair();
        String publicKey = keyPair.getPublicKey();
        String privateKey = keyPair.getPrivateKey();
        System.out.println("New key pair created.");
        System.out.println("Public key: " + publicKey);
        System.out.println("Private key: " + privateKey);
        String textToSign = "这里是要被数字签名的文字。";
        System.out.println("Text to sign: " + textToSign);
        String signature = signatureToolbox.signText(textToSign, privateKey);
        System.out.println("Signature: " + signature);
        System.out.println("Verify signature: " + signatureToolbox.verifyTextSign(textToSign, publicKey, signature));
    }

    static class SignatureToolbox {
        private static final String KEY_PAIR_GENERATOR_ALGORITHM = Main.KEY_PAIR_GENERATOR_ALGORITHM;
        private static final int KEY_SIZE = Main.KEY_SIZE;
        private static final String SIGNATURE_ALGORITHM = Main.SIGNATURE_ALGORITHM;
        private static final int FILE_BUFFER_SIZE = Main.FILE_BUFFER_SIZE;

        private static SignatureToolbox instance;

        private SignatureToolbox() {
        }

        public static SignatureToolbox getInstance() {
            if (instance == null) {
                instance = new SignatureToolbox();
            }
            return instance;
        }

        public KeyPairBase64 createKeyPair() throws NoSuchAlgorithmException {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_PAIR_GENERATOR_ALGORITHM);
            keyPairGenerator.initialize(KEY_SIZE);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            return new KeyPairBase64(keyPair);
        }

        public String signText(String text, String privateKeyBase64) throws Exception {
            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
            signature.initSign(base64ToPrivateKey(privateKeyBase64));
            signature.update(text.getBytes());
            byte[] signedBytes = signature.sign();
            return toBase64(signedBytes);
        }

        public String signFile(String filePath, String privateKeyBase64) throws Exception {
            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
            signature.initSign(base64ToPrivateKey(privateKeyBase64));
            BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(filePath));
            byte[] buffer = new byte[FILE_BUFFER_SIZE];
            int len;
            while ((len = bufferedInputStream.read(buffer)) >= 0) {
                signature.update(buffer, 0, len);
            }
            bufferedInputStream.close();
            byte[] signedBytes = signature.sign();
            return toBase64(signedBytes);
        }

        public boolean verifyTextSign(String text, String publicKeyBase64, String signatureBase64) throws Exception {
            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
            signature.initVerify(base64ToPublicKey(publicKeyBase64));
            signature.update(text.getBytes());
            byte[] signatureBytes = base64ToByteArray(signatureBase64);
            return signature.verify(signatureBytes);
        }

        public boolean verifyFileSign(String filePath, String publicKeyBase64,
(/@Ta/2023-05-14 16:56//)

回复需要登录

6月29日 15:34 星期天

本站由hu60wap6驱动

备案号: 京ICP备18041936号-1