188 lines
4.5 KiB
Java
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));
|
|
|
|
}
|
|
|
|
}
|