2011-10-18 11:14:08 +02:00

188 lines
4.5 KiB
Java

import java.lang.Math;
import java.math.BigInteger;
import java.util.Random;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class RSA {
final static BigInteger m =
new BigInteger("91011121314151617181920212223242526272829",10);
BigInteger p = new BigInteger("0",10);
BigInteger q = new BigInteger("0",10);
BigInteger phi = new BigInteger("0",10);
BigInteger e = new BigInteger("0",10);
BigInteger sha = new BigInteger("0",10);
BigInteger n = new BigInteger("0",10);
BigInteger d = new BigInteger("0",10);
BigInteger encrypted = new BigInteger("0",10);
BigInteger decrypted = new BigInteger("0",10);
//Generates a PrimNumber
private BigInteger genPrim(int bitlen){
BigInteger p = BigInteger.probablePrime(bitlen, new Random());
if(!p.isProbablePrime(100000)){
throw new RuntimeException();
}
return p;
}
//Generates an E using phi
private void genE(BigInteger phi){
e = genPrim(256);
if(!phi.gcd(e).equals(BigInteger.ONE)){
genE(phi);
}
}
//Encrypt-Funktion
public void encrypt(){
q = genPrim(256); //get q
p = genPrim(256); //get p
if(p.equals(q)){ //ensure p!=q
encrypt();
}
phi = p.subtract(BigInteger.ONE).multiply(
q.subtract(BigInteger.ONE)); //phi=(p - 1)(q - 1)
n = p.multiply(q); //n = p*q
genE(phi); //get e
SHA256(); //calculate Hash of m
encrypted = expModuloN(sha, e, n); // hash^e mod n
}
//Decrypt Function (you need 2 run encrypt first)
public void decrypt(){
d = extEuklid(e, phi); //calculate d
decrypted = expModuloN(encrypted, d, n); //decrypt
}
//extended Euklid-Algorithm
private BigInteger extEuklid(BigInteger a, BigInteger b){
//Ancor
if(b.equals(BigInteger.ZERO)){
return BigInteger.ONE;
}
//Initialize vars
BigInteger x1 = new BigInteger("0",10);
BigInteger x2 = new BigInteger("1",10);
BigInteger y = new BigInteger("1",10);
BigInteger y1 = new BigInteger("1",10);
BigInteger y2 = new BigInteger("0",10);
BigInteger r = new BigInteger("0",10);
BigInteger q = new BigInteger("0",10);
BigInteger x = new BigInteger("0",10);
while(b.compareTo(BigInteger.ZERO) == 1){
q = a.divide(b);
r = a.mod(b);
x = x2.subtract(q.multiply(x1));
y = y2.subtract(q.multiply(y1));
a = b;
b = r;
x2 = x1;
x1 = x;
y2 = y1;
y1 = y;
}
if(x2.compareTo(BigInteger.ZERO) == -1){
x2 = phi.add(x2);
}
return x2; //only x2 is needed
}
//Efficient m^e mod n
private BigInteger expModuloN(BigInteger m, BigInteger e, BigInteger n){
BigInteger b = m;
BigInteger r = BigInteger.ONE;
for(int i = 0; i <= e.bitLength(); i++){
if(e.testBit(i)){
r = r.multiply(b).mod(n);
}
b = b.multiply(b).mod(n);
}
return r;
}
//Converts a byte to a HexString
public String BytetoHex(byte b) {
int value = (b & 0x7F) + (b < 0 ? 128 : 0);
String ret = (value < 16 ? "0" : "");
ret += Integer.toHexString(value).toUpperCase();
return ret;
}
//Converts SHA-byte-array to HexString
public String SHAtoHex(byte[] d)
{
StringBuffer buf = new StringBuffer();
for (int i = 0; i < d.length; i++) {
buf.append(BytetoHex(d[i]));
}
return buf.toString();
}
//Calculates SHA256 of m
private void SHA256(){
try {
MessageDigest l = MessageDigest.getInstance("SHA-256");
l.reset();
l.update(m.toByteArray());
sha = new BigInteger(SHAtoHex(l.digest()), 16);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException();
}
}
public static void main(String[] args) {
RSA r = new RSA();
r.encrypt(); //calculate all
r.decrypt();
//Print all
System.out.println("\nKey public:");
System.out.println("\t e: " + r.e);
System.out.println("\t n: " + r.n);
System.out.println("\nKey private:");
System.out.println("\t d: " + r.d);
System.out.println("\nHashvalue:");
System.out.println("\t sha: " + r.sha);
System.out.println("\nSignature:");
System.out.println("\t Enc.: " + r.encrypted);
System.out.println("\nDecrypted:");
System.out.println("\t Dec.: " + r.decrypted);
System.out.println("\nSHA = Decrypted:");
System.out.println(r.decrypted.equals(r.sha));
}
}