Domanda Risolto C++ Miracl RSA

arlequim

Utente Bronze
2 Settembre 2014
13
3
9
48
Buon pomeriggio a tutti,
da qualche giorno ho deciso di buttarmi sul C++ come principale linguaggio utilizzato per implementare la crittografia con la libreria Miracl, che per un principiante come me risulta piuttosto facile dato che ha una buona documentazione e sul web si trovano tanti esempi. Allora ho preso un esempio di RSA+Crt (pk-demo.cpp) e dopo averlo linkato con la libreria x64 compilata da me, risulta perfettamente funzionante fino a 1024 bit. Purtroppo se genero p e q con 2048 bit, il programma mi da errore in corrispondenza dell'output di cout. Non conoscendo il C++, presumo che ci possa essere un errore legato alla lunghezza dell'output, ma questo lo chiedo a qualche esperto che certamente potrà risolvere molto velocemente questo mio quesito da puro newbie. Qui sotto il listato e l'output su console. Grazie in anticipo a chiunque vorrà gentilmente intervenire. Ciaooo!!! :)

Codice:
    SetConsoleTextAttribute(hConsole, 4);
    cout << "\n*** Now generating 2048-bit random primes p and q, then calculate n ..." << endl;
    for(;;) 
    {
        p=rand(1024*2,2);
        if (p%2==0) p+=1;
        while (!prime(p)) p+=2;

        q=rand(1024*2,2);
        if (q%2==0) q+=1;
        while (!prime(q)) q+=2;

        n=p*q;

        e=65537;
        phi=(p-1)*(q-1);
        if (gcd(e,phi)!=1) continue;
        d=inverse(e,phi);
        break;
    }

    SetConsoleTextAttribute(hConsole, 15);
    cout <<"\np=" << p << endl;
    cout <<"\nq=" << q << endl;
    cout <<"\nn=p*q=" << n << endl;

Codice:
*** Now generating 2048-bit random primes p and q, then calculate n ...

p=30981519717916345767084068504480330252269195696873928280843407540446865462354207030052342902159602166882707751155427719454798225804387713841577017148259376441628770611912017369615871196645732404776702227390285887684718182609545962633740045799106365659614173277902815508634298749691460249904055045705563251465636049931472429472366181398900038567726425954140620095198230174096442456915151333909958999526516957473395714321218838172588538170630394424612091143992120207861667803684730278611024049307527426524861856605637886136280895134980317750931034192440324871714420559893046460618652535801942511054393994259551349247541

q=31985407324293729397174030251266099061523246140809783875823849135067898108503721784178839062636567764060047212556404284153076116757331721257175458794098237449640334748646670222608767142571543457542733040738579344335494403141326644209328278531340934389489232786111702464160413683726545570987062226013608809244970061374951117454028462304149111924812016060588450804560822689915645344484119191705168843467694925177506796078551447678833038067500528583870673544284281667860101506574991043266494478739013384274195814950346522801655968576719946790117147508912542924348455103995168823101138757377950398039616184244235147013791

n=p*q=
MIRACL error from routine otstr
              called from cotstr
              called from your program
I/O buffer overflow
 
  • Mi piace
Reazioni: Helplease
Non conoscevo questa libreria, vedendo il codice su github sembra che fornisca diverse primitive per la crittografia. Pero' se posso darti un suggerimento evita di reinventare la ruota, specie in crittografia e' pericoloso. Ti consiglio di usare librerie come OpenSSL che sono altrettanto ben documentate ed espongono funzioni per generare le chiavi in modo piu' semplice, lasciando la parte matematica completamente trasparente.
Riguardo l'errore sembra che sia in grado di calcolarlo correttamente, il problema si verifica solo nel convertirlo in stringa (eccezione lanciata e catturata da miracl), per cui potresti saltare il print di n e continuare con il programma.
 
Ciao, grazie della risposta. Effettivamente Miracl non è la libreria crittografica più completa ed efficiente al giorno d'oggi, ma è forse la più indicata a puro scopo didattico per imparare ad implementare RSA e curve ellittiche non tralasciando però alcune nozioni di base dei big numbers su cui si appoggiano. E in tutti i casi il mio obiettivo, almeno in questo momento, è quello di ripassare le direttive di compilazione e la sintassi del C, poi passerò definitivamente al C++.
Ovviamente cambierò la libreria di appoggio, che sarà Crypto++, anch'essa molto utilizzata (come da autodesk) quando si parla di ECDSA o ECDH, ma con molte altre funzioni di crittografia. Quindi non mi passa nemmeno per la testa di reinventare la ruota, semplicemente devo togliere un po' di ruggine, e forse talvolta addentrarsi in qualche concetto matematico non può e non deve "nuocere alla salute". Riguardo all'errore, sono pienamente d'accordo con quanto hai detto tu, e in tutti i casi ho già scritto all'autore della libreria. Vediamo se e cosa risponde. Buona serata!!! ;)
 
Non mi sono messo a testare, ma a guardare Github questa libreria è ferma da praticamente 8 anni con qualche bug fix fatto 3 anni fa. Anche se fosse solo per roba didattica, mi accodo a JunkCoder nel suggerirti di passare ad altro. Se proprio la vuoi fare super didattica puoi anche provare ad implementare direttamente i big numbers, tanto alla fine devi usare solo operazioni di base (+, -, *, /) e algoritmi molto semplici (gdc modulare e inversa).

e forse talvolta addentrarsi in qualche concetto matematico non può e non deve "nuocere alla salute"
A tal proposito, lasciami spammare un po' la mia guida su RSA. Avevo usato GMP (una famosa libreria C per i big numbers) per implementare gli attacchi.
 
Ultima modifica:
Giusto, la libreria Miracl è ormai a tutti gli effetti datata, se non fosse per qualche sporadico bugfix di qualche anno fa. Mi limiterò a fare qualche altro programmino con ECDSA e poi passerò definitivamente a Crypto++, anche se non parlano affatto male delle librerie Botan. Queste ultime due sono entrambe scritte in C++, per cui una volta acquisita la sintassi del linguaggio e i concetti matematici di base, non dovrebbero dare dei grossi problemi nel gestire una p l'altra. Sarà invece da valutare la velocità di calcolo, ma qui si apre un universo perchè contro le primitive del compilatore intel c'è poco da fare :) Miracl è sicuramente adatto per chi si avvicina a questo mondo e ha alcune funzioni davvero carine, come mad, moltiplicazione, addizione e divisione, del tipo ((x*y)+z)/w, che restituisce oltretutto con eventuale resto in r.
Messaggio unito automaticamente:

Ho trovato la soluzione, bastava solamente aumentare la costante che definisce la dimensione del buffer I/O, ovvero IOBSIZ. Questo è l'output del programmino RSA ->

Codice:
*** Now generating 2048-bit random primes p and q, then calculate n ...

p=F56BC0C6CF330ACA1BA476AD72C3DEDEB7E84DEDF01BFCF24815DFBFD304A0C753F6C772CF25B6FEF86213BF23F8D4B5CCCB52A3F3FAE203A59BC327EF93B06472019E268DE08FC6E3F8BFCFF54C5475F56D884FD8401EDB129AF1BDCC877DCC58AE65D6A3A173410DBB587234A7F4B1EB9F1B520C6D4365D94211099C8598EFE3C1CF86269E583CA0E546D89394DB43AE35B27A4367E6F219037E03E5EA86F85484F5781D9F5B7F546FB930189A7A8BD2A790CA0A1C5A0A9B32C783BFC8FAD0769C944EACEA64D4404EC3D1BEA20216E28357518FBECBB87076F960234E2615DD3A087A31DC3B2E8897D5C6F3417D041DEE2E780948F19332936B5E89FA0E35

q=FD5F8C20EE47955ACBC9A739C8F63330CE9D1867DA1D96FD9D4656B9E8718C035BC2140E2D9957FAF20DFD7814551D39A96B1237A97CFF594980206B126B6DFFA02F0B1C492F120F388749D1296BBB4DFBCC5DD19599452012A27DB09C4279D66B65549E68E832D9D30D6D4B4C4353E059D789FA2D2151ABC26B3ACC7FA3F476CF621F3A1149F170CB32DCAB373532666B88A6B8245AE8558079ACA6A26F216D5E843943F8EFD64DE25D9DBD7165FDF6B587DD6294D1E2D1452734EEBB0D02007AEFD61E21B5DD5158EF0102591D38B958C0CB31374A9A97A9D653EB47FA42A9B9BB7F91FF389DB03284B73D1ECA882A0F8A8180B8CDAA7885E193B70CD9EE9F

n=p*q=F2E716D783DFF50E9CD1D728FE06D3C3E0127FD7A18364518AA9A7B4B4D284DD78565E2EF985F1DF17665D599D093D9BBDCCB1C686CE54964A78B171AEA3C096D1ECC308BB0E64248DA5B77BAA6C9D9D0A8E95E861526B644B9276673D36E0D7940B7713F06AD5812F3C55B5447D84F76A4FF31019B6B3ABBE3B62BDEC74DC3220EE87346FF4727D3583720DC5158C07CF5C4CC9B61EB5ED14D3042B825037455F3D77FF1D37C22BB3CA8E31336EFC8540D208B2E5A6BDB7B4C1EE994C2097D40A20851E6889CBA179E2537D70261F8D8F6F5C1CB7926F01BE635E81DE5DF745F337FB167CCFEDA6F8F4454BFD316F7A644BF8A2E963229F0AB7BAE2092D0F98DF47C36B2EFAE421DFB557A510244386D2B01F1F81854C413C936F4415CD1FBD367551DCAA279D2908C92EA8E1BC42AA3126F54D328A47FD73CF7AC20F9AC58C8A5A5A7E857DE66E376B5322DE8A57B663209E545AE2226CCCF7DAD6AB0565773B4D6C578F748FCF8C4F871CCDDE6697B3F33959117F3DFF23C5F1AADEF22A7BB1164950F2EBDBD660394DC8A752E0EE673622957ED947DEE8180295C37862D113DFC75114F61FA58955B7775FCD0515A21AC47D3DA419662DE2C4C498F08211354712B9C06D346906F3F0C2507AB9715036AC1B961573F686415A2A521E9BE36D3F99744FA3BB5CB1BD4A6F6E277F23A5DD22D8BDEFBE3F2679D881B27118EB

*** Encrypting test string 'It always seems impossible until it's done.' ...

Ciphertext=56E2BBEF534F348AC17985446CF529721BBDFC7D104351DC5E70EFAA1AB644C6C761DF0CA49FA393390FB9C898D4041FADA64406C2471FEBB9EFE368FEB0E42FF9A06FA1AD327EAC62EEFBE5A1BD7247FC623682C3F49469C93AF7602ADFAF35C0631AB6C504DA203DC39388B5EBF1216C83FA0DB98E68468D3A0B81B6DC5B49D5A677AA66D68B392EF49C83F9B981F082A3E154D27D71725FDBDD461D9CAD749D5B34A92D9DA1F1C5367A9674E13360966B129B5E081299EA2F47F21604DE14BB0903281F18FFCFA870FFCBE1873FC70CFDF30258ED61E1FEFD998C73056B86A08338B7C4468AAA267D4F96AFD35B35D27818CE30E0084B75A40EE1AF6757D041B3D4FDBAA74395C76F69E1B2CF2632BA54FE53B07FD1F0ED0E5ECA4215562F114E269BE317078DC959C9CB3AC7F0E3991C09008B212ABB5065785E9BA1900F08E9E0F7A91C832B34A5D6D0C6B16603461FB331D7D9C1E657E3B643BB0C81BF3CB2C7A70717E1FA937A5432708B140EEFFEEA3C81226C1F68926C53B84C8F98371C3ABBE0A06ECC5CC035C68B5E2179EF3806F95493522EA5C43644415AEF004F15A610D9D1437DD4B57F266DB1FBEAC4462C4AB184E097E5BD80558C01388B191398D213482054BF0F6585F9923E36E02ED17B5CBC78236EF21A460564574FD1E732F4224C0F586852156639688378F1E4708B938F43A56CA86103E17DB479

*** Decrypting test string ...

Plaintext='It always seems impossible until it's done.'


*** Ok!