0

我正在将字节数组写入带符号哈希的文本文件,我首先将其转换为 base64 字符串,然后在写入文本文件之前使用编码 UTF-8 再次转换为字节数组,我目前的问题是当我得到了字节我不知道如何转换为原始格式以使用公钥验证我的签名哈希,有人知道将其转换回来吗?

这就是我将原始字节转换为能够写入文本文件的方式:

        public static byte[] ConvertToBase64(byte[] bytes)
        {
            string base64 = Convert.ToBase64String(bytes);
            return Encoding.UTF8.GetBytes(base64);
        }

这就是我签署哈希的方式:

        private byte[] signData(byte[] dataValue)
        {
            X509Certificate2 privateKey = new X509Certificate2(privateKeyfileName, password);

            //Encryting/Signing a hash
            using (ECDsa ecdsa = privateKey.GetECDsaPrivateKey())
            {
                if (ecdsa == null) throw new Exception("Not an ECDSA cert, or has no private key");

                return ecdsa.SignData(dataValue, HashAlgorithmName.SHA256);
            }
        }

这就是我创建哈希的方式:

        // The cryptographic service provider.
        private SHA256 Sha256 = SHA256.Create();

        // Compute the file's hash.
        private byte[] GetHashSha256FromFile(string filename)
        {
            using (FileStream stream = File.OpenRead(filename))
            {
                return Sha256.ComputeHash(stream);
            }
        }

如果我可以从原始签名哈希中获取值,这就是我应该如何验证签名哈希:

        private bool verifyData(byte[] dataValue, byte[] dataSigned)
        {
            byte[] mycertCer = Properties.Resources.mycertCer;
            X509Certificate2 publicKey = new X509Certificate2(mycertCer, password);

            //Checking the hash and signature
            using (ECDsa ecdsa = publicKey.GetECDsaPublicKey())
            {
                if (ecdsa == null) throw new Exception("Not an ECDSA cert, or has no private key");

                return ecdsa.VerifyData(dataValue, dataSigned, HashAlgorithmName.SHA256);
            }
        }

我将不胜感激任何帮助,如果您需要更多详细信息,请告诉我。

4

1 回答 1

1

签名是二进制数据,因此您可以将其存储为原始字节(例如以任何扩展名 .bin 结尾的文件)

public static byte[] readFileBytes(String filepath) throws Exception {
    return Files.readAllBytes(Paths.get(filepath));
}

public static void writeFileBytes(String filepath, byte[] input) throws Exception {
    try (FileOutputStream fos = new FileOutputStream(filepath)) {
        fos.write(input);
    }
}

如果您真的想将此二进制/字节数组存储到文本文件中,则必须使用 base64 或十六进制安全编码:

public static String fromBytesToBase64(byte[] dataBytes) {
    return Base64.getEncoder().encodeToString(dataBytes);
}

public static byte[] fromBase64ToBytes(String base64String) {
    return Base64.getDecoder().decode(base64String);
}

流程将如下所示:

byte[] signature = getTheSignatureAfterSignOperation();
String signatureInBase64 = fromBytesToBase64(signature);
saveToTextfile(signatureInBase64, "anyFile.txt");

// Other side
String signatureBase64 = readTextFile("anyFile.txt");
byte[] originalSignature = fromBase64ToBytes(signatureBase64);
doVerficiation(originalSignature);
于 2021-11-22T22:57:27.010 回答