gpt4 book ai didi

java - 将 BouncyCaSTLe 签名转换为 Crypto++ 格式

转载 作者:行者123 更新时间:2023-11-30 05:04:21 25 4
gpt4 key购买 nike

关于 ECDSA sign with BouncyCastle and verify with Crypto++ 给出的示例, DSAConvertSignatureFormat() 需要 byte[] 作为参数。但是我从我的 Java 代码中得到的是一个像这样的签名,它是一个 String:

302e021500f16529dcaddd3cec7616a3f94e157d1c28df8ea9021500997de4ae5497268c4f8eb3129abb11ca2abea9c1

如何在 Crypto++ 代码中使用 Java 签名?


这是问题中的 Crypto++ 代码:

bool VerifyMessage( const ECDSA<ECP, SHA256>::PublicKey& key, const string& message, const string& signature )
{
bool result = false;
string signatureFromJava("302e021500cb3333768bbe3f26d7a58388015d6110c1dbad5f021500dc2ee848c72deee1542939b3e5eb2816e71bf895");
SecByteBlock signatureFromJavaByte((byte *)signatureFromJava.data(), signatureFromJava.size());

byte finalSignature[0x40];
DSAConvertSignatureFormat(finalSignature, sizeof(finalSignature), DSA_P1363,
signatureFromJavaByte, sizeof(signatureFromJavaByte), DSA_DER);

// TODO convert finalSignature to std::string


// Hexa encoding version, more readable
std::string decodedSignature;
StringSource(signature, true,
new HexDecoder(
new StringSink(decodedSignature)));

StringSource(decodedSignature+message, true,
new SignatureVerificationFilter(ECDSA<ECP,SHA256>::Verifier(key),
new ArraySink((byte*)&result,
sizeof(result))));

return result;
}

这里是有问题的 Java 代码:

public static String sign(String data) throws Exception {
KeyPair keyPair = loadKeyPair(System.getProperty("user.dir"),"ECDSA");
Signature signature = Signature.getInstance("SHA256withECDSA", "BC");
signature.initSign(keyPair.getPrivate(), new SecureRandom());
byte[] message = data.getBytes();
signature.update(message);
byte[] sigBytes = signature.sign();
//verify("TEST", sigBytes);
String signatureStr = new BigInteger(1, sigBytes).toString(16);
return signatureStr;
}

最佳答案

Comment: it crashes on DSAConvertSignatureFormat() call

byte finalSignature[0x40];
DSAConvertSignatureFormat(finalSignature, sizeof(finalSignature), DSA_P1363,
signatureFromJavaByte, sizeof(signatureFromJavaByte), DSA_DER);

崩溃是因为 sizeof(signatureFromJavaByte)std::string 的大小,而不是字符串的长度。 std::string 是 16 字节左右。这包括 8 个字节的指针和 8 个字节来保存指向的数据的大小。没有向函数传递 66 到 72 个字节,而是只提供了 16 个左右的字节。

我认为该功能还有其他问题,因此您可能想朝另一个方向前进。


How do I use the Java signature in the Crypto++ code?

您可以使用类似于下面的代码。

您应该使用模式 &str[0] 来获取指向字符串第一个元素的非常量指针。据我所知,这是获取非常量指针的唯一明确定义的方法。其他一切都可能导致未定义的行为。

#define LOG_TAG "MY_PRODUCT"
#define LOG_DEBUG(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
#define LOG_INFO(...) ((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
#define LOG_WARN(...) ((void)__android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__))
#define LOG_ERROR(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))

bool VerifyMessage( const ECDSA<ECP, SHA256>::PublicKey& key, const string& message, const string& javaSignature )
{
ECDSA<ECP, SHA256>::Verifier verifier(key);
string ieeeSignature(0x40, '\0');

size_t size = DSAConvertSignatureFormat(
reinterpret_cast<byte*>(&ieeeSignature[0]), ieeeSignature.size(), DSA_P1363,
reinterpret_cast<const byte*>(&javaSignature[0]), javaSignature.size(), DSA_DER);
ASSERT(size == 0x40);

bool result = verifier.VerifyMessage(
reinterpret_cast<const byte*>(&message[0]), message.size(),
reinterpret_cast<const byte*>(&ieeeSignature[0]), ieeeSignature.size());

if (result)
LOG_INFO("VerifyMessage: verified message");
else
LOG_WARN("VerifyMessage: failed to verify message");

return result;
}

像下面这样调用它。

string javaSignature("302e021500cb3333768bbe3f26d7a58388015d6110c1dbad5f021500dc2ee848c72deee1542939b3e5eb2816e71bf895");
string derSignature; // Hex decoded signature

StringSource(javaSignature, true, new HexDecoder(new StringSink(derSignature)));

bool verified = VerifyMessage(key, message, derSignature);

您还可以添加如下函数,将任意签名从 DER 转换为 P1363:

std::string DER2P1363(const std::string& signature)
{
std::string result;
result.resize(256);

size_t size = DSAConvertSignatureFormat(
reinterpret_cast<byte*>(&result[0]), result.size(), DSA_P1363,
reinterpret_cast<const byte*>(&signature[0]), signature.size(), DSA_DER);

result.resize(size);
return result;
}

256 是最大字符串长度。转换 DER 签名后会调整大小。

关于java - 将 BouncyCaSTLe 签名转换为 Crypto++ 格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48947765/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com