- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我使用 Crypto++ (libcrypto++ 1.11) 在我的应用程序中嵌入 JWT。我制作了使用 CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>
签名和验证消息的方法算法(带有 secp256r1
曲线)。用于验证的 token 可以来自外部世界,因此我需要在知道公钥的情况下验证 token 内容(文本数据)签名。
问题是 Crypto++ 会导致无效签名的 SegFault,这给我的 Web 服务器带来了很多痛苦。
我希望 BER 格式(库中默认的序列化格式)的签名具有固定长度,所以我只需要将签名的长度与某个常量进行比较即可。但是,我发现更大的内容会产生更大的签名,因此需要更深入的方法。
bool ES256Verifier::Verify(const std::string& data,
const std::string& signature) {
bool result = false;
try {
CryptoPP::StringSource ss(
signature + data, true,
new CryptoPP::SignatureVerificationFilter(
verifier_,
new CryptoPP::ArraySink((byte*)&result, sizeof(result))));
} catch (const CryptoPP::BERDecodeErr& err) {
LOG_WARNING() << "Signature `" << signature << "` has invalid (non-BER) format";
} catch (const CryptoPP::Exception& ex) {
LOG_WARNING() << "Signature verification has failed: " << ex.what();
}
return result;
}
验证者 verifier_
已正确初始化(并成功验证 token ,除了 SegFaults),但给定 data = ""
和 signature = ""
,例如,我总是得到 SegFault:
__memmove_avx_unaligned_erms 0x00007fb4b9da6b38
CryptoPP::ArraySink::Put2(unsigned char const*, unsigned long, int, bool) 0x00007fb4ba414fb2
CryptoPP::BufferedTransformation::ChannelPut2(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned char const*, unsigned long, int, bool) 0x00007fb4ba3acedc
CryptoPP::StringStore::CopyRangeTo2(CryptoPP::BufferedTransformation&, unsigned long long&, unsigned long long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool) const 0x00007fb4ba414e02
CryptoPP::BufferedTransformation::Peek(unsigned char*, unsigned long) const 0x00007fb4ba3ad74a
CryptoPP::Integer::Decode(CryptoPP::BufferedTransformation&, unsigned long, CryptoPP::Integer::Signedness) 0x00007fb4ba45885c
CryptoPP::Integer::Decode(unsigned char const*, unsigned long, CryptoPP::Integer::Signedness) 0x00007fb4ba458c16
CryptoPP::DL_VerifierBase<CryptoPP::ECPPoint>::InputSignature pubkey.h:1560
CryptoPP::SignatureVerificationFilter::LastPut(unsigned char const*, unsigned long) 0x00007fb4ba4159a0
CryptoPP::FilterWithBufferedInput::PutMaybeModifiable(unsigned char*, unsigned long, int, bool, bool) 0x00007fb4ba418107
CryptoPP::BufferedTransformation::ChannelPut2(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned char const*, unsigned long, int, bool) 0x00007fb4ba3acedc
CryptoPP::BufferedTransformation::TransferMessagesTo2(CryptoPP::BufferedTransformation&, unsigned int&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool) 0x00007fb4ba3ad8fa
CryptoPP::BufferedTransformation::TransferAllTo2(CryptoPP::BufferedTransformation&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool) 0x00007fb4ba3adb21
CryptoPP::SourceTemplate<CryptoPP::StringStore>::PumpAll2 filters.h:1238
CryptoPP::Source::PumpAll filters.h:1182
CryptoPP::Source::SourceInitialize filters.h:1215
CryptoPP::StringSource::StringSource filters.h:1271
jwt::signature::algorithm::ES256Verifier::Verify es256_verifier.cpp:40
ES256_SignatureTest_Test::TestBody es256_test.cpp:29
...
那么,有没有办法查看数据和签名,并确定这种特定组合是否会由于签名长度无效而导致 SegFault?
最佳答案
下面是一些使用字段元素、签名者和验证者确定签名长度的示例代码。第一个输出打印元素长度和 r||s
长度,因为 r||s
是 P1363 格式的签名。
第二个和第三个输出只是打印SignatureLength()
的结果。您的程序应该拒绝短于 SignatureLength()
的签名。甚至尝试验证一个简短的签名也没有意义,因为它不好。
请注意:这仅适用于 DL_*
签名方案(基于离散日志)。它不适用于TF_*
签名方案(基于陷门函数)。
#include "cryptlib.h"
#include "eccrypto.h"
#include "osrng.h"
#include "oids.h"
#include <iostream>
int main(int argc, char* argv[])
{
using namespace CryptoPP;
AutoSeededRandomPool prng;
///// Element
DL_GroupParameters_EC<ECP> params(ASN1::secp256r1());
unsigned int elemLength = params.GetCurve().GetField().MaxElementByteLength();
std::cout << "Element length: " << elemLength << std::endl;
std::cout << "r||s length: " << 2*elemLength << std::endl;
///// Signer
ECDSA<ECP, SHA256>::Signer signer;
signer.AccessKey().Initialize(prng, params);
unsigned int signerLength = signer.SignatureLength();
std::cout << "Signer signature length: " << signerLength << std::endl;
///// Verifier
ECDSA<ECP, SHA256>::Verifier verifier(signer);
unsigned int verifierLength = verifier.SignatureLength();
std::cout << "Verifier signature length: " << verifierLength << std::endl;
return 0;
}
运行程序结果如下。
$ ./test.exe
Element length: 32
r||s length: 64
Signer signature length: 64
Verifier signature length: 64
如果将曲线切换为 ASN1::secp521r1()
,则运行程序会产生以下结果。
$ ./test.exe
Element length: 66
r||s length: 132
Signer signature length: 132
Verifier signature length: 132
关于c++ - 如何从 Crypto++ ECDSA 中的签名体获取签名长度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57872901/
我需要创建由“根”证书(自签名,ECDSA)签名的“客户端”ECDSA 证书。“根”证书是按照 Translating Elliptic Curve parameters (BC to MS) 中的描
理论上,如果拥有公钥、签名和已签名的数据并且哈希算法已知,则应该可以验证一段数据的签名。 我有二进制格式的所有这些组件。有人知道验证此签名的最简单方法吗?打开SSL? Python?一个例子会很棒。不
我正在使用ECC证书来观察TLS是如何工作的,谁能帮我区分ECDH-ECDSA-AES128-SHA256和 ECDHE-ECDSA-AES128-SHA256 . 使用时ECDHE-ECDSA-AE
我在执行以下操作时遇到问题: 使用 Python 为 ECDSA SECP256k1 曲线创建公私钥对,并将其打印在终端上。 在 Python 脚本和 visual studio(使用 micro-e
我正在尝试生成用于加密芯片的“原始”、未编码的 ECDSA 签名。目标是在主机 pc 上签署某些内容,然后将其发送到芯片进行验证。但是,我遇到了一个小问题。我的理解是 ECDSA 签名应该是 64 个
我需要使用 ECDSA 算法对消息进行签名并在 java 中发送给接收者。然后,接收方应验证发送方的签名。 因此,为此,接收方拥有发送方的公钥,但在通过以下命令将 java.security.Publ
我正在使用创建 key 对 ECDSA::Signer signer; signer.AccessKey().Initialize(randomGeneratorM, ASN1::secp160r1(
我只需要为 ECDSA 获取私钥和公钥对。 Stanford Javascript Crypto Library 以非标准方式 ( https://groups.google.com/forum/
我一直在为以太坊交易管理器编写签名者服务,我需要使用 Google KMS Golang APIs 签署以太坊交易。 .我将在下面尝试总结我面临的问题。 Ethereum 在 R 中需要紧凑的 RLP
我使用以下两行来生成 ECDSA 私钥的十六进制: openssl ecparam -genkey -name secp256k1 -out data.pem openssl ec -in data.
我正在使用 python 和 cryptography.io 来签署和验证消息。我可以通过以下方式获得签名的 DER 编码字节表示: cryptography_priv_key.sign(messag
是否有为 JWK 创建指纹(又名指纹)的标准规范方法? 从我阅读的内容来看,该标准似乎没有定义 kid应该指定,我觉得很奇怪。对我来说,它是最重要的,因为它是一个确定性的值,而不是一个需要查找表的值,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭 8 年前。 Improve
我想知道ECDSA签名和公钥的数据格式是什么规范(或标准)定义的? 我正在 java 卡上测试 ECDSA 签名。我发现签名和公钥值中有一个TLV格式。 * Public key (TV format
我正在尝试创建一个数字证书,该证书将使用 EC key 而不是来自 RSA 的 key 进行自签名,并遵循这些 SO link1和 link2 。我将 link1 中给出的 RSA 签名算法替换为 E
我正在尝试创建一个数字证书,该证书将使用 EC key 而不是来自 RSA 的 key 进行自签名,并遵循这些 SO link1和 link2 。我将 link1 中给出的 RSA 签名算法替换为 E
以下网站经常被引用,我认为是准确的: https://gobittest.appspot.com/Address 我正在尝试在 Golang 中重现这些步骤,但第一步失败:-( 有人可以向我提供一个
我试图从私钥生成公共(public) ECDSA key ,但我没有在互联网上找到关于如何执行此操作的太多帮助。几乎一切都是为了从公钥规范生成公钥,但我不知道如何获得它。到目前为止,这是我整理的内容:
是否有任何库支持从 javascript(前端)的私钥派生 ecdsa 公钥? (有了私钥,我们就可以生成对应的公钥) 我研究了localethereum white paper ,我想实现加密层。
来自OpenSSL documentation 使用命名曲线 prime256v1(又名 P-256)创建给定 SHA-256 哈希值的 ECDSA 签名。 第二步:使用 ECDSA_do_sign(
我是一名优秀的程序员,十分优秀!