在ECDSA sign with BouncyCastle and verify with Crypto++给出的示例中,jenkins@jenkins-87c47bbb8-g87nw:/$ps -aux
[...]
jenkins [..] -jar /usr/share/jenkins/jenkins.war --argumentsRealm.passwd.jenkins=password --argumentsRealm.roles.jenkins=admin
[...]
需要DSAConvertSignatureFormat()
作为参数。但是从我的Java代码中得到的是,我得到了一个像byte[]
:
String
如何在Crypto ++代码中使用Java签名?
以下是问题中的Crypto ++代码:
302e021500f16529dcaddd3cec7616a3f94e157d1c28df8ea9021500997de4ae5497268c4f8eb3129abb11ca2abea9c1
以下是有问题的Java代码:
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;
}
答案 0 :(得分:1)
评论:它在DSAConvertSignatureFormat()调用
上崩溃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个字节。
我认为该功能有其他问题,所以你可能想要朝另一个方向前进。
如何在Crypto ++代码中使用Java签名?
您可以使用类似于以下的代码。
您应该使用模式&str[0]
来获取指向字符串第一个元素的非const指针。据我所知,它是获取非const指针的唯一明确定义的方法。其他一切都可能导致不确定的行为。
#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签名后调整大小。