Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Probleme bei RSA-Verschlüsselung

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
08.11.2007, 22:26 Uhr
Tino



Hallo.
Ich versuche seit einigen Tagen eine RSA Verschlüsselung zu schreiben, aber irgendwie will es nicht... Das schlimmste ist, dass es kein(e) Syntaxfehler sind, aber trotzdem das Programm abschmiert und "beendet werden muss".

Ich füge ma den quelltext ein

C++:
#include <iostream.h>
#include <math.h>
#include <string>
unsigned main()
{
  using namespace std;
  string ein,zwi;
  unsigned arr[5000];  //10.000 Zeichen max. verschlüsselbar
  getline(cin,ein);
  zwi.resize(ein.size());
  for (unsigned i=0;i<ein.size();i++)
    {

      if (ein[i]==32) zwi[i]=0;
      else
    zwi[i]=ein[i]-96;
    }

  for (unsigned i=0;i<(ein.size()/2);i++)
    {

      if (i==0) arr[0]=(zwi[0]*100)+(zwi[1]);
      else
    arr[i]=(zwi[2*i]*100)+zwi[(2*i)+1];
    }
  for (unsigned i=0;i<(zwi.size()/2);i++)
    {
      cout<<arr[i]<<endl;
    }
  unsigned N,D,E,p,q,z;
  unsigned i;
  cout<<"Die wievielte Primzahl soll p sein?!";
  cin>> i;
  cout<<"Die wievielte Primzahl soll q sein?!";
  unsigned h;
  cin>> h;
  cout<<"Die wievielte Primzahl < (p-1)*(q-1)="<<z<<">0 soll E sein?!";
  unsigned m;
  cin>> m;
  unsigned k=0;
  for(unsigned j=1;;)
    {
      bool isprim=true;
      unsigned teiler= (j/2)+1;
      for(;teiler>1;teiler--)
    {
      if (j%teiler==0) isprim=false;
    }
      if (isprim) {k++;cout<<j<<endl;}
      j++;
      if (k==i) {p=--j;break;}
    }

  unsigned l=0;
  for(unsigned j=1;;)
    {
      bool isprim=true;
      unsigned teiler= (j/2)+1;
      for(;teiler>1;teiler--)
    {
      if (j%teiler==0) isprim=false;
    }
      if (isprim) {l++;cout<<j<<endl;}
      j++;
      if (l==h) {q=--j;break;}
    }



  N=p*q;
  z=(p-1)*(q-1);


  unsigned n=0;
  for(unsigned j=z-1;;j--)
    {
      bool isprim=true;
      unsigned teiler= (j/2)+1;
      for(;teiler>1;teiler--)
    {
      if (j%teiler==0) isprim=false;
    }
      if (isprim) {n++;cout<<j<<endl;}

      if (n==m) {E=--j;}
      if(z%E!=0) break;
    }
  for(unsigned i=z;i>1;i--)
    {
      if ((i*E)%z==1)
    {D=i;break;}
      cout<<i;  
    }
  unsigned  arr2[5000];
  for (unsigned i=0;i<(ein.size()/2);i++) {arr2[i]=1;}
  cout<<endl<<"N= "<<N<<endl<<"E= "<<E<<endl<<"D= "<<D<<endl;
  for (unsigned j=0;i<((ein.size())/2);j++)
    {
      arr2[j]=arr[j];
      for (unsigned i=0 ; i<E; i++)
    {
      arr2[j]=(arr2[j]*arr2[j])%N;
    }
                                                            
    }

  for (unsigned i=0;i<(ein.size())/2;i++)
    {cout<<arr2[i]<<" ";}
  getchar();
  return 0;
}



Der (oder die?! :-( ) Fehler sind unter der Zeile "N=p*q;"
Findet irgendwer welche?!

Würde mich über Hilfe sehr freuen!

Liebe Grüße! Tino


Bearbeitung von 0xdeadbeef:

Code durch ident gejagt, für bessere Lesbarkeit


Dieser Post wurde am 08.11.2007 um 22:38 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
08.11.2007, 22:41 Uhr
xXx
Devil


Keine Syntax-Fehler? Dann wechsel mal den Compiler:

C++:
#include <iostream.h>
#include <math.h>
#include <string>
unsigned main()

=>

C++:
#include <iostream>
#include <cmath>
#include <string>

int main() {
usw. also es sollte schon ein anderer Compiler sein :P
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
08.11.2007, 23:51 Uhr
0xdeadbeef
Gott
(Operator)


Hmm...ist ziemlich unüberschaubar in der Form. Warum spaltest dus nicht ein bisschen auf, in mehrere Funktionen? Dadurch wirds deutlich übersichtlicher. In diesem Fall würde es zum Beispiel Sinn machen, eigene Funktionen für das Generieren von Primzahlen, den erweiterten euklidischen Algorithmus, und Modulo-Potenzierung zu schreiben. Ich hatte grad nichts besseres zu tun, also hab ich meine Zeit mal damit totgeschlagen:

C++:
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <vector>

struct ext_euklid_info {
  long d, s, t;
};

ext_euklid_info ext_euklid(unsigned long a, unsigned long b) {
  ext_euklid_info ret = { a, 1, 0 };
  
  if(b != 0) {
    ext_euklid_info tmp = ext_euklid(b, a % b);
    ret.d = tmp.d;
    ret.s = tmp.t;
    ret.t = tmp.s - a / b * tmp.t;
  }

  return ret;
}

unsigned long mult_inverse_mod(unsigned long x, unsigned long phi) {
  ext_euklid_info info = ext_euklid(x, phi);

  return (info.s + phi) % phi;
}

bool is_prime(unsigned long x, std::vector<unsigned long> primes) {
  for(int i = 0; primes[i] * primes[i] <= x; ++i) {
    if(x % primes[i] == 0)
      return false;
  }

  return true;
}

std::vector<unsigned long> generate_primes(std::size_t num) {
  std::vector<unsigned long> primes(2);

  primes[0] = 2;
  primes[1] = 3;

  for(int i = 5, j = 2; primes.size() < num; i += j, j = 6 - j) {
    if(is_prime(i, primes))
      primes.push_back(i);
  }

  return primes;
}

unsigned long pow_mod(unsigned long base, unsigned long exp, unsigned long mod) {
  unsigned long base_mod = base % mod;

  if(exp == 0) return 1;

  if(exp % 2 == 0) {
    return pow_mod(base_mod * base_mod % mod, exp / 2, mod);
  }

  return base_mod * pow_mod(base_mod, exp - 1, mod) % mod;
}

int main() {
  std::vector<unsigned long> primes;
  unsigned long p, q, N, phi, d, e, C, K, K_c;

  std::srand(std::time(0));

  primes = generate_primes(1000);

  p = primes[62];
  q = primes[148];

  N = p * q;
  phi = (p - 1) * (q - 1);

  // e muss nicht prim sein, sondern lediglich teilerfremd zu phi
  do {
     e = rand() % (phi / 10);
  } while(ext_euklid(e, phi).d != 1);

  d = mult_inverse_mod(e, phi);

  std::cout << "p:   " << p << std::endl
        << "q:   " << q << std::endl
        << "phi: " << phi << std::endl;
  std::cout << "pubkey : (" << e << ", " << N << ")" << std::endl
        << "privkey: (" << d << ", " << N << ")" << std::endl;

  K = 12345;
  C = pow_mod(K, e, N);
  K_c = pow_mod(C, d, N);

  std::cout << K << ", " << C << ", " << K_c << std::endl;
}


Wenn du das verwenden willst, wirst dus noch auf char-arrays tweaken müssen; das hier ist mehr so ne Art Referenzimplementierung. Davon aber mal ganz abgesehen, es wäre wahrscheinlich am sinnvollsten, du würdest dafür eine Krypto-Bibliothek verwenden, wie z.B. libgcrypt oder openssl, die haben da noch nämlich noch ne ganze Reihe an sicherheitstechnischen Tricks drauf, die ich hier nicht alle erschlagen kann - memory locking und so weiter.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
12.11.2007, 17:49 Uhr
~Tino
Gast


Ich danke, werd es aber trotzdem doch lieber selbst schreiben^^ Jedoch hat mir dein Code auf jeden weitergeholfen!

Ich werde aber eher nich ne krypto bibi verwenden, da es n schulprojekt is, und ich daher wohl doch eher die Funktionen selber schreiben werde^^

Nun denn!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
15.11.2007, 11:06 Uhr
~Tino
Gast


Ok. habs nu nochma überarbeitet, bin and der stelle wo er wieder anfangen soll mit D zu entschlüsseln...
Und diesma is alles logisch und so... trotzdem kommen sogar teilweise negative Zahlen herraus!

Wenn jemand nen Fehler erkennen kann, wär ich doch recht verbunden mir den mitzuteilen..
Danke im Vorraus ;-)


C++:
// C++ Trainer, 13.11.2007, all rights reserved
#include <iostream.h>
using namespace std;
string blocktext(string);
int prim(int);
int ggT(int ,int );
int blockpaare(string,int);
int modpow(int,int,int);
int main()
{
string eingabe,ausgabe;
cout<<"geben sie text ein!\n";
getline(cin,eingabe);
ausgabe=blocktext(eingabe);
cout<<"Blockpaare: ";
for(unsigned i=0;i<eingabe.size()/2;i++)
{cout<<blockpaare(ausgabe,i)<<" ";}
cout<<endl<<"Geben sie ein die wievielte Primzahl p sein soll!"<<endl;
int p;
cin>>p;
p=prim(p);
cout<<endl<<"p= "<<p;
cout<<endl<<"Geben sie ein die wievielte Primzahl q sein soll!"<<endl;
int q;
cin>>q;
q=prim(q);
cout<<endl<<"q= "<<q;
int N=p*q;
int z=(p-1)* (q-1);
int E,hilfE;
for(;;)
{
E=(rand()%z);
hilfE=E;
if (ggT(E,z)==1){ break;}

}
cout<<endl<<endl<<"E= "<<hilfE<<endl<<endl<<"N= "<<N;
int D;
for(int i=z;;i++)
{
if((i*hilfE)%N==1){D=i;break;}
}
cout<<endl<<"D= "<<D<<endl<<endl;

int code[5000];
for(unsigned i=0;i<eingabe.size()/2;i++)
{
code[i]=modpow( blockpaare(ausgabe,i),E,N  );
}
cout<<"ihr verschlüsselter Text: "<<endl;
for(unsigned i=0;i<eingabe.size()/2;i++)
{
cout<<code[i]<<" ";
}

getchar();
cout<<"entschlüsseln?!"<<endl;
getchar();
for (unsigned i=0;i<eingabe.size()/2;i++)
{cout<<modpow(code[i],D,N)<<" ";}
getchar();
  return 0;
}

string blocktext(string ein)
{
string zwi;
zwi.resize(ein.size());
for (unsigned i=0;i<ein.size();i++)
{

if (ein[i]==32) zwi[i]=0;
else
zwi[i]=ein[i]-96;
}
return zwi;
}
int blockpaare(string ein,int i)
{
int arr[5000];
for (unsigned i=0;i<(ein.size()/2);i++)
{

if (i==0) arr[0]=(ein[0]*100)+(ein[1]);
else
arr[i]=(ein[2*i]*100)+ein[(2*i)+1];
}
int ausgabe=arr[i];
return ausgabe;
}
int ggT(int a,int b)
{
    int hilf;
    while (b>0)
    {
        if (b>a)
        {
            hilf = a;
            a = b;
            b = hilf;
        }
        a = a - b;
    }
    
   return a;
}
int prim(int n)
{
int k=0;
int prim;
for(int i=2;;i++)
        {
        bool isprim=true;
        if(i==2)k++;
        else
        {
        for(int teiler=(i/2)+1;teiler>1;teiler--)
                {
                if(i%teiler==0)isprim=false;
                }
         if (isprim)k++;
         }
         if(k==n){prim=i;break;}
         }
return prim;
}
int modpow(int Klar,int E,int N)
{
int erg=1;
for (int i=0;i<E;i++)
{
erg=erg*Klar;
erg=erg%N;
}
  return erg;
}
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
15.11.2007, 11:29 Uhr
0xdeadbeef
Gott
(Operator)


Bei der Berechnung der Potenz ergeben sich gerne mal sehr große Zwischenergebnisse. Rechne da lieber zwischenzeitlich mit long, sonst laufen dir die Variablen über.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
15.11.2007, 11:37 Uhr
~Tino
Gast


Daran lags nicht.. habe alle unsigned und int in unsigned long umgeschrieben. Das verhalten bleibt das gleiche. danke trotzdem für die antwort, weil länger is bei verschlüsselungen ja eigentlich recht sinnvoll^^
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: