2016-06-14 9 views
2

У меня есть алгоритм n, d, e для RSA. Тем не менее, я хочу использовать private_key для шифрования некоторой строки, генерировать USER_CERTIFICATION и использовать public_key для пользователей, чтобы расшифровать ее и получить строку. Я знаю, что если я так, строка может быть легко расшифрован кем-либо, но безопасность не моего беспокойства вообще, мне просто нужно что никто, кроме меня не может генерировать USER_CERTIFICATIONИспользование Crypto ++ RSA :: PublicKey для дешифрования шифрованного текста

Я используя CryptoPP код для кодирования работает отлично:

Integer _n(...), _e(...), _d(...); 
AutoSeededRandomPool rng; 
RSA::PrivateKey k; 
k.Initialize(_n, _e, _d); 
RSAES_PKCS1v15_Encryptor enc(k); 
std::string cipher; 
StringSource ss1(plain, true, 
    new PK_EncryptorFilter(rng, enc, 
     new StringSink(cipher)) // PK_EncryptorFilter 
    ); // StringSource 

но код дешифровки выдает исключение: "класс CryptoPP :: InvertibleRSAFunction: отсутствует необходимый параметр" Prime1"

Integer _n(...), _e(...); 

AutoSeededRandomPool rng; 
RSA::PublicKey k; 
k.Initialize(_n, _e); 
RSAES_PKCS1v15_Decryptor dec(k); 
std::string plain; 
StringSource ss1(cipher, true, 
    new PK_DecryptorFilter(rng, dec, 
     new StringSink(plain)) 
    ); // StringSource 

Возможно ли это сделать с помощью CryptoPP?

+0

Как вы сделали здесь? Любые сюрпризы остаются? – jww

ответ

2

Я хочу использовать private_key зашифровать некоторую строку

Обычно, когда вы просите шифруют с закрытым ключом, что вы хотите, этого вероятностной Подписи с Recovery (PSSR) схемой , Кстати, шифруют с закрытым ключом является не действительный криптографическое преобразование :)

cryptlib.h header описывается как Абстрактные базовые классы, которые обеспечивают унифицированный интерфейс для этой библиотеки. Все Crypto ++ Signers и Verifiers придерживаются интерфейса PK_SignatureScheme. Подписывающие устройства дополнительно реализуют PK_Signer, а Verifiers дополнительно реализуют PK_Verifier.

Объекты Crypto ++ RSA будут выглядеть так:

RSASS<PSSR, SHA256>::Signer signer; 
RSASS<PSSR, SHA256>::Verifier verifier; 

Объекты Crypto ++ Рабин будут выглядеть так:

RabinSS<PSSR, SHA256>::Signer signer; 
RabinSS<PSSR, SHA256>::Verifier verifier; 

Объекты Crypto ++ Рабин-Williams будет выглядеть следующим образом:

RWSS<PSSR, SHA256>::Signer signer; 
RWSS<PSSR, SHA256>::Verifier verifier; 

Объекты согласованы, и вы можете их менять.

Кстати, вы должны изучить Рабина-Уильямса, чтобы убедиться, что он соответствует вашим потребностям. Также см. Файл Bernstein's RSA signatures and Rabin–Williams signatures: the state of the art.


Я использую CryptoPP код для кодирования отлично работает ...

лома. Показатель, который вы используете, хорошо известен, поэтому нет никакой реальной безопасности в том, что вы делаете. Есть способы улучшить безопасность, но похоже, что вы хотите использовать PSSR.

Вот два примера использования PSSR RSA от вики:

А вот подписывающий код RSA Probabilistic Signature Scheme with Recovery с некоторыми из ваших вещей набрали. Обратите внимание, что вам нужен реальный RandomNumberGenerator, потому что подпись рандомизирована.

Integer n(...), e(...), d(...); 
RSA::PrivateKey key(n,e,d); 
RSASS<PSSR, SHA256>::Signer signer(key); 

//////////////////////////////////////////////// 
// Sign and Encode 
SecByteBlock signature(signer.MaxSignatureLength(messageLen)); 

AutoSeededRandomPool rng; 
size_t signatureLen = signer.SignMessageWithRecovery(rng, message, messageLen, NULL, 0, signature); 

// Resize now we know the true size of the signature 
signature.resize(signatureLen); 

А вот проверяющий код RSA Probabilistic Signature Scheme with Recovery с некоторыми из ваших вещей набранных. Обратите внимание, что вам не нужно RandomNumberGenerator, так что вы можете использовать NullRNG(), если его нужно где-то.

Integer n(...), e(...); 
RSA::PublicKey key(n,e); 
RSASS<PSSR, SHA256>::Verifier verifier(key); 

//////////////////////////////////////////////// 
// Verify and Recover 
SecByteBlock recovered(
    verifier.MaxRecoverableLengthFromSignatureLength(signatureLen) 
); 

DecodingResult result = verifier.RecoverMessage(recovered, NULL, 0, signature, signatureLen); 

if (!result.isValidCoding) { 
    throw Exception(Exception::OTHER_ERROR, "Invalid Signature"); 
} 

//////////////////////////////////////////////// 
// Use recovered message 
// MaxSignatureLength is likely larger than messageLength 
recovered.resize(result.messageLength); 

... но код дешифровки выдает исключение: "класс CryptoPP :: InvertibleRSAFunction: отсутствует необходимый параметр 'Prime1'"

Да, шифровать с частным ключ является не действительная криптографическая трансформация. Я уверен, что расшифровать с помощью открытого ключа является не действует, либо :)


Я не собираюсь предоставлять код для шифрования и дешифрования, так как я не верю тебе нужно это. Но вы можете найти его на RSA Encryption Schemes на вики Crypto ++.

+0

ПодписьWithRecovery работает, но не может обрабатывать сообщение размером более 128 байт. Разделение длинного сообщения на многие 128-байтовые куски кажется не очень хорошей идеей. Теперь я использую 'a_exp_b_mod_c (message, d, n)' для самой кодировки. – aj3423

+0

@ aj3423 - Просто так нет сюрпризов ... ваше сообщение все еще слишком велико. 'a_exp_b_mod_c' молча усекает его. Если вы выполните обратное преобразование, вы получите усеченное сообщение. Проверьте [Raw RSA] (http://www.cryptopp.com/wiki/Raw_RSA) и изучите сообщение, которое вы восстановили (соответствующий раздел [Private Key Encryption] (http://www.cryptopp.com/wiki/Raw_RSA # Private_Key_Encryption)). Чтобы избежать усечения: возможно ли увеличить размер модуля или использовать меньшее сообщение? – jww

+0

@ aj3423 - Также убедитесь, что вы действительно хотите отказаться от рандомизации подписи. В цитированной статье Бернштейна говорится о том, почему вы хотите рандомизировать подпись в разделе 5. Атаки на нерандомизированные подписи наблюдаются с 1979 года. – jww

0

Итак, вы хотите подписать сообщение своим личным ключом? У этой ссылки есть пример, возможно, это помогает (код и ссылка ниже). Также обратите внимание, что не все подписи - это шифрование. Например, ECDSA, используемый Биткойном, использует операцию подписи, которая принимает случайное число в качестве одного входа, а шифрование не выполняется как часть подписи.

https://www.cryptopp.com/wiki/User_Guide:_rsa.h

void Sign() 
{ 
string strContents = "A message to be signed"; 
//FileSource("tobesigned.dat", true, new StringSink(strContents)); 

AutoSeededRandomPool rng; 

//Read private key 
CryptoPP::ByteQueue bytes; 
FileSource file("privkey.txt", true, new Base64Decoder); 
file.TransferTo(bytes); 
bytes.MessageEnd(); 
RSA::PrivateKey privateKey; 
privateKey.Load(bytes); 

//Sign message 
RSASSA_PKCS1v15_SHA_Signer privkey(privateKey); 
SecByteBlock sbbSignature(privkey.SignatureLength()); 
privkey.SignMessage(
    rng, 
    (byte const*) strContents.data(), 
    strContents.size(), 
    sbbSignature); 

    //Save result 
    FileSink sink("signed.dat"); 
    sink.Put((byte const*) strContents.data(), strContents.size()); 
    FileSink sinksig("sig.dat"); 
    sinksig.Put(sbbSignature, sbbSignature.size()); 
} 
+0

@jwwYes, но мне кажется, что он хочет сделать, это классический алгоритм compute-hash-of-msg-> encrypt - hash-with-private-key. Затем получатель может проверить аутентификацию msg, используя открытый ключ sender: s, если этот ключ проверен CA и доверен. –