Код:
import java.math.BigInteger;
import java.security.MessageDigest;
import java.util.Random;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class JavaCrypto {
private static final int AES_BLOCK_SIZE = 16;
private static final String SRP_USER = "User";
private static final byte colon = 58;
private static boolean debug = false;
public static final int SRP_SALT_BITS = 80;
public static final int SRP_SALT_BYTES = 10;
public static final int SRP_VERIFIER_BYTES = 1024;
static final byte[] SRP_MODULUS = new byte[] {
-1, -1, -1, -1, -1, -1, -1, -1, -55, 15,
-38, -94, 33, 104, -62, 52, -60, -58, 98, -117,
Byte.MIN_VALUE, -36, 28, -47, 41, 2, 78, 8, -118, 103,
108, -70, -50, -44, -69, 27, -37, Byte.MAX_VALUE, 20, 71,
-26, -52, 37, 75, 51, 32, 81, 81, 43, -41,
89, -25, -55, Byte.MAX_VALUE, -66, -57, -24, -13, 35, -87,
122, 126, 54, -52, -120, -66, 15, 29, 69, -73,
20, -52, 94, -46, 15, Byte.MIN_VALUE, 55, -32, -89, -105,
-38, 86, -55, -20, 46, -14, -106, 50, 56, Byte.MAX_VALUE,
-123, -35, -6, -99, 75, Byte.MAX_VALUE, -94, -64, -121, -24,
121, 104, 51, 3, -19, 91, -35, 58, 6, 43,
-56, 31, 86, -24, Byte.MIN_VALUE, -71, 110, 113, 96, -55,
Byte.MIN_VALUE, -35, -104, -19, -45, -33, -1, -1, -1, -1,
-1, -1, -1, -1 };
static final byte[] SRP_GENERATOR = new byte[] { 19 };
public static void main(String[] args) {
try {
String vncmetadata = "VNCpaswd";
String metadata = "This is Password";
byte[] encryptedBytes = AES_encrypt(vncmetadata.getBytes("UTF-8"));
System.out.println("AES encryption successful" + ((encryptedBytes != null && encryptedBytes.length > 0) ? 1 : 0));
byte[] hashedBytes = SHA1_hash(metadata.getBytes("UTF-8"));
System.out.println("SHA1 Hash successful" + ((hashedBytes != null && hashedBytes.length > 0) ? 1 : 0));
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Generating SRP Verifier and salt...");
System.out.println();
String password = new String("String");
SRP_Verifier_Salt svs = GenerateSRPVerifier(password);
System.out.println("Outer verifier size: " + svs.verifier.length);
System.out.println();
int i;
for (i = 0; i < svs.verifier.length; i++)
System.out.print("[" + svs.verifier[i] + "] ");
System.out.println();
System.out.println();
System.out.println("Outer salt size: " + svs.salt.length);
System.out.println();
for (i = 0; i < svs.salt.length; i++)
System.out.print("[" + svs.salt[i] + "] ");
System.out.println();
}
public static byte[] AES_encrypt(byte[] plainText) throws Exception {
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128);
SecretKey sKey = keyGen.generateKey();
SecretKey sIV = keyGen.generateKey();
byte[] rawKey = sKey.getEncoded();
byte[] rawIV = sIV.getEncoded();
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKey key = new SecretKeySpec(rawKey, "AES");
IvParameterSpec iv = new IvParameterSpec(rawIV);
cipher.init(1, key, iv);
byte[] cipherText = cipher.doFinal(plainText);
byte[] result = new byte[48];
for (int i = 0; i < 16; i++) {
result[3 * i] = rawKey[i];
result[3 * i + 1] = rawIV[i];
result[3 * i + 2] = cipherText[i];
}
return result;
}
public static String AES_decrypt(byte[] cipherText) throws Exception {
byte[] text2decrypt = new byte[16];
byte[] key = new byte[16];
byte[] iv = new byte[16];
for (int i = 0; i < 16; i++) {
key[i] = cipherText[3 * i];
iv[i] = cipherText[3 * i + 1];
text2decrypt[i] = cipherText[3 * i + 2];
}
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(iv);
cipher.init(2, keySpec, ivSpec);
byte[] results = cipher.doFinal(text2decrypt);
return new String(results, "UTF-8");
}
public static byte[] SHA1_hash(byte[] plainText) throws Exception {
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(plainText);
return md.digest();
}
public static synchronized SRP_Verifier_Salt GenerateSRPVerifier(String password) {
for (int i = 0; i < 10; i++) {
try {
SRP_Verifier_Salt srp_vs = GenerateOneTimeSRPVerifier(password);
if (srp_vs != null)
return srp_vs;
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Regenerating verifier...");
}
return null;
}
private static synchronized SRP_Verifier_Salt GenerateOneTimeSRPVerifier(String password) throws Exception {
MessageDigest sha = MessageDigest.getInstance("SHA-1");
SRP_Verifier_Salt vs = new SRP_Verifier_Salt();
byte[] salt = GenerateSRPSalt();
if (debug == true) {
System.out.println("Salt size: " + salt.length);
System.out.println("Salt: ");
for (int i = 0; i < salt.length; i++)
System.out.print("[" + salt[i] + "] ");
System.out.println();
}
sha.update("User".getBytes());
sha.update((byte)58);
sha.update(password.getBytes());
byte[] digest = sha.digest();
if (debug == true) {
System.out.println();
System.out.print("#(u+\":\"+p) =");
System.out.println();
for (int i = 0; i < digest.length; i++)
System.out.print("[" + digest[i] + "] ");
System.out.println();
}
sha.reset();
sha.update(salt);
sha.update(digest);
digest = sha.digest();
if (debug == true) {
System.out.println();
System.out.print("#(s+#(u+\":\"+p)) =");
System.out.println();
for (int i = 0; i < digest.length; i++)
System.out.print("[" + digest[i] + "] ");
System.out.println();
}
BigInteger x = new BigInteger(1, digest);
BigInteger g = new BigInteger(1, SRP_GENERATOR);
BigInteger n = new BigInteger(1, SRP_MODULUS);
BigInteger v = g.modPow(x, n);
byte[] verifier = v.toByteArray();
if (debug == true) {
System.out.println("Verifier size: " + verifier.length);
for (int i = 0; i < verifier.length; i++)
System.out.print("[" + verifier[i] + "] ");
System.out.println();
}
if (verifier.length == 1024) {
vs.salt = salt;
vs.verifier = verifier;
return vs;
}
if (verifier.length == 1025 && verifier[0] == 0) {
vs.salt = salt;
vs.verifier = new byte[1024];
System.arraycopy(verifier, 1, vs.verifier, 0, 1024);
return vs;
}
return null;
}
public static synchronized byte[] GenerateSRPSalt() {
for (int i = 0; i < 10; i++) {
try {
byte[] rnd_num = GenerateOneTimeSRPSalt();
if (rnd_num != null)
return rnd_num;
Thread.sleep(100L);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Regenerating salt...");
}
return null;
}
public static synchronized byte[] GenerateOneTimeSRPSalt() {
BigInteger big_rnd_num = new BigInteger(80, new Random());
byte[] rnd_num = big_rnd_num.toByteArray();
if (rnd_num.length == 10)
return rnd_num;
if (rnd_num.length == 11 && rnd_num[0] == 0) {
byte[] rnd_num_2 = new byte[10];
System.arraycopy(rnd_num, 1, rnd_num_2, 0, 10);
return rnd_num_2;
}
return null;
}
}