Can any one help me write decrypt method for my XOR encryptor. So how i'm encrypt:
I'm making XOR
public static String idEncrypt(String id, String key)throws Exception
{
if (id == null)
return null;
if (key.length() == 0)
return id;
String utfID="", utfKey="";
try
{
utfID = new String(id.getBytes(), "UTF-8");
utfKey = new String(key.getBytes(), "UTF-8");
}
catch (UnsupportedEncodingException e)
{
Log.e("utf8", "conversion", e);
}
StringBuilder sb = new StringBuilder();
for(int i = 0; i < utfID.length(); i++)
sb.append((char)(utfID.charAt(i) ^ utfKey.charAt(i % utfKey.length())));
String result = sb.toString();
return toHex(result.getBytes());
}
Converting bytes to hex:
public static String toHex(byte[] buf) {
if (buf == null)
return "";
StringBuffer result = new StringBuffer(2*buf.length);
for (int i = 0; i < buf.length; i++) {
appendHex(result, buf[i]);
}
return result.toString();
}
private final static String HEX = "0123456789abcdef";
private static void appendHex(StringBuffer sb, byte b) {
sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));
}
Actually all of my trying to decrypt result of this crypts failed =(
May be some on explains me how work with it?
P.S: the results of my trying is strings like "X¨»¾RkÖ_êQ", but must be 16 symbols of numbers and letters.
UPD:
My fromHEX() method
public static String fromHex(String hex) {
return new String(toByte(hex));
}
public static byte[] toByte(String hexString) {
int len = hexString.length()/2;
byte[] result = new byte[len];
for (int i = 0; i < len; i++)
result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();
return result;
}
Related
I've got a class MCrypt in Java (in an android App), it's working well, but i need to translate it in Swift 4.
Here my Class in Java
public class MCrypt {
private String SecretKey = "0pw3av67$979cdxf";
private Cipher cipher;
private String iv = "xe95bmad7x5432p8";
private IvParameterSpec ivspec = new IvParameterSpec(this.iv.getBytes());
private SecretKeySpec keyspec = new SecretKeySpec(this.SecretKey.getBytes(), "AES");
public MCrypt() {
try {
this.cipher = Cipher.getInstance("AES/CBC/NoPadding");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e2) {
e2.printStackTrace();
}
}
public byte[] encrypt(String str) throws Exception {
if (str != null) {
if (str.length() != 0) {
try {
this.cipher.init(1, this.keyspec, this.ivspec);
return this.cipher.doFinal(padString(str).getBytes());
} catch (Exception e) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("[encrypt] ");
stringBuilder.append(e.getMessage());
throw new Exception(stringBuilder.toString());
}
}
}
throw new Exception("Empty string");
}
public byte[] decrypt(String str) throws Exception {
if (str != null) {
if (str.length() != 0) {
try {
this.cipher.init(2, this.keyspec, this.ivspec);
return this.cipher.doFinal(hexToBytes(str));
} catch (Exception e) {
System.out.println(e);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("[decrypt] ");
stringBuilder.append(e.getMessage());
throw new Exception(stringBuilder.toString());
}
}
}
throw new Exception("Empty string");
}
public static String bytesToHex(byte[] bArr) {
if (bArr == null) {
return null;
}
int length = bArr.length;
String str = "";
for (int i = 0; i < length; i++) {
StringBuilder stringBuilder;
if ((bArr[i] & 255) < 16) {
stringBuilder = new StringBuilder();
stringBuilder.append(str);
//stringBuilder.append(AppEventsConstants.EVENT_PARAM_VALUE_NO);
stringBuilder.append(Integer.toHexString(bArr[i] & 255));
str = stringBuilder.toString();
} else {
stringBuilder = new StringBuilder();
stringBuilder.append(str);
stringBuilder.append(Integer.toHexString(bArr[i] & 255));
str = stringBuilder.toString();
}
}
return str;
}
public static byte[] hexToBytes(String str) {
if (str == null || str.length() < 2) {
return null;
}
int length = str.length() / 2;
byte[] bArr = new byte[length];
for (int i = 0; i < length; i++) {
int i2 = i * 2;
bArr[i] = (byte) Integer.parseInt(str.substring(i2, i2 + 2), 16);
}
return bArr;
}
private static String padString(String str) {
int length = 16 - (str.length() % 16);
for (int i = 0; i < length; i++) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(str);
stringBuilder.append(' ');
str = stringBuilder.toString();
}
return str;
}}
You can use it like that :
String testst = "03e91bc1d6c14ad806832f98cf567830561460c565c9f1db426be13e86007c53d8171e1e7d7265c24ad84a0d3c4d346c59bd676ed3f2b2a6c4bde44b541c6a9697c63244c84483817b59e3dd3ac9bd76b9665b1495df06ab64939644221e58bfbf3624cc06af1679833ad8f7430a6314e3eb0a449c59a1f9ea093fc670bd7abab73f0f9ce7e1f74de6a34f4e4bbde6a8c4a44befffbdb020382730c2f99fdcc54319478168150d188d482306c6cc15252b21fc4c569d25cf5d2135b03612c73cd4f066b97b08a8bcd3f82f3158dcd692c33752d3fd0d85f22c841bf4b7ab8adeb9963bc16702baa38e041bbdab9bd7bc786fd5330d3a9d277dbe0ef331e1e5db6a4fc56b19210f694d1be6bc7939027da7fed1b8c412780daf93c033149bb2a90fcda46a8f54edaee3316622e7ec84d3ea831c724607614584aa2b7b882181d4291d0b1a2c73d34a41778125a7a44f7a";
String mastring = new String(new MCrypt().decrypt(teststring));
Result is
{"tempsnews":false,"imagenews":"","comments":"","relatednews":"","rnews":"","banned":"","banneduk":"","bannedus":"","bannedca":"","bannedau":"","bannedfr":"","bannedeg":"","bannedsa":"","bannedma":"","bannedsportfr":"","bannedbefr":"","bannedae":"","bannedflashbn":"","bannedglobal":"","bannedhmo":"","bannedng":"","bannednigeria":""}
For swift i use CryptoSwift (https://github.com/krzyzanowskim/CryptoSwift) and i start working on the decrypt function.
From the first step it looks easier than in Java but i can not make it works.
This is my method in Swift:
func aesDecrypt(encryptedString: String,key: String, iv: String) throws -> String {
let input: [UInt8] = Array(encryptedString.utf8)
let decrypted: Array<UInt8> = try AES(key: Array(key.utf8), blockMode: CBC(iv: Array(iv.utf8)), padding: .noPadding).decrypt(input)
let decryptedData = Data(decrypted)
return String(bytes: decryptedData.bytes, encoding: .utf8) ?? "Could not decrypt"
}
and you can call like htaht :
var strencrypted = "03e91bc1d6c14ad806832f98cf567830561460c565c9f1db426be13e86007c53d8171e1e7d7265c24ad84a0d3c4d346c59bd676ed3f2b2a6c4bde44b541c6a9697c63244c84483817b59e3dd3ac9bd76b9665b1495df06ab64939644221e58bfbf3624cc06af1679833ad8f7430a6314e3eb0a449c59a1f9ea093fc670bd7abab73f0f9ce7e1f74de6a34f4e4bbde6a8c4a44befffbdb020382730c2f99fdcc54319478168150d188d482306c6cc15252b21fc4c569d25cf5d2135b03612c73cd4f066b97b08a8bcd3f82f3158dcd692c33752d3fd0d85f22c841bf4b7ab8adeb9963bc16702baa38e041bbdab9bd7bc786fd5330d3a9d277dbe0ef331e1e5db6a4fc56b19210f694d1be6bc7939027da7fed1b8c412780daf93c033149bb2a90fcda46a8f54edaee3316622e7ec84d3ea831c724607614584aa2b7b882181d4291d0b1a2c73d34a41778125a7a44f7a"
var k = "0pw3av67$979cdxf" // 16 Bit Key
var iv = "xe95bmad7x5432p8" // 16 Bit Vector
do {
let deccc = try aesDecrypt(encryptedString: strencrypted, key: k, iv: iv)
print(deccc)
} catch {
print('error')
}
I missed something somewhere, but where ! Thanks in advance
After running a Junit test for String serialization, it is failed and gave me the following results:
Expected: "netmodel"
Actual: "l"
The serialize method as follows
public static void serializeString(String objectToSerialize, OutputStream outputStream) {
byte[] bytesArr = objectToSerialize.getBytes();
serializeInt(bytesArr.length, outputStream);
try {
outputStream.write(bytesArr);
} catch (IOException e) {
e.printStackTrace();
}
}
And my deserialize method as follows
public static String deserializeString(InputStream inputStream) {
String deserializeObject = "";
char asciiToChar;
int stringByteArrayLength = deserializeInt(inputStream);
byte[] databytesArr = new byte[stringByteArrayLength];
try {
inputStream.read(databytesArr, 0, stringByteArrayLength);
}
catch (IOException e) {
e.printStackTrace();
}
for (int i = 0; i < databytesArr.length; i++) {
asciiToChar = (char) databytesArr[i];
deserializeObject = "" + Character.toString(asciiToChar);
}
return deserializeObject;
}
Finally, I wrote a unit test as follows
public class StringSerializerTest {
private InputStream iStream;
private ByteArrayOutputStream oStream;
#Before
public void init() {
oStream = new ByteArrayOutputStream();
}
String serialzeAndDeserializeObject(String stringValue) {
OutputStreamUtil.serializeString(stringValue, oStream);
iStream = new ByteArrayInputStream(oStream.toByteArray());
return InputStreamUtil.deserializeString(iStream);
}
#Test
public void equals_equal() {
String stringValue = "netmodel";
String deserializedStringValue = serialzeAndDeserializeObject(stringValue);
assertThat(deserializedStringValue).isEqualTo(stringValue);
}
}
what was wrong? and how to fix it?
You are reassigning the entire value of deserializeObject during each iteration of
for (int i = 0; i < databytesArr.length; i++) {
asciiToChar = (char) databytesArr[i];
deserializeObject = "" + Character.toString(asciiToChar);
}
This results in only the last character (l in this case) being stored in deserializeObject. This loop should append the next character to the deserializeObject as in the following:
for (int i = 0; i < databytesArr.length; i++) {
asciiToChar = (char) databytesArr[i];
deserializeObject += Character.toString(asciiToChar);
}
The corrected deserialization logic would be:
public static String deserializeString(InputStream inputStream) {
String deserializeObject = "";
char asciiToChar;
int stringByteArrayLength = deserializeInt(inputStream);
byte[] databytesArr = new byte[stringByteArrayLength];
try {
inputStream.read(databytesArr, 0, stringByteArrayLength);
}
catch (IOException e) {
e.printStackTrace();
}
for (int i = 0; i < databytesArr.length; i++) {
asciiToChar = (char) databytesArr[i];
deserializeObject += Character.toString(asciiToChar);
}
return deserializeObject;
}
The error was already reported by Justin Albano.
However take also care of strings with non-ASCII: like special characters.
Something like the following. Also one should close at the end to ensure flushing in case of a buffered stream. And theoretically a read could yield only a non-blocking part of the array. DataOutputStream has nice methods, though you seem to roll your own serialisation.
public static void serializeString(String objectToSerialize, OutputStream outputStream)
throws IOException {
byte[] bytesArr = objectToSerialize.getBytes(StandardCharsets.UTF_8);
serializeInt(bytesArr.length, outputStream);
outputStream.write(bytesArr);
}
public static String deserializeString(InputStream inputStream)
throws IOException {
int stringByteArrayLength = deserializeInt(inputStream);
byte[] databytesArr = new byte[stringByteArrayLength];
readFully(inputStream, databytesArr);
return new String(databytesArr, StandardCharsets.UTF_8);
}
private static void readFully(InputStream inputStream, byte[] bytes) throws IOException {
int i = 0;
while (i < bytes.length) {
int nread = inputStream.read(bytes, i, bytes.length - i);
if (nread <= 0) {
throw new IOException("Premature EOF");
}
i += nread;
}
}
Mind that StandardCharsets is not in Android SDK, only standard Java.
The java code below generates a SHA-256 hash of the input msg, using the key. However, all my attempts to write code that does same operation in C# have not yielded the same results given same input. I would need help getting the C# equivalent as I have tried a lot already with little success.
I think I've been able to translate most of the code into C# correctly, apart from the part which updates the digest (m.update()), first with the key, then later with the message before hashing.
JAVA CODE
public static String generateHash256Value(String msg, String key) {
MessageDigest m = null;
String hashText = null;
System.out.println("Value to hash::::::::::" + msg);
byte[] actualKeyBytes = HexToByte(secret_key);
try {
m = MessageDigest.getInstance("SHA-256");
m.update(actualKeyBytes, 0, actualKeyBytes.length);
try {
m.update(msg.getBytes("UTF-8"), 0, msg.length());
}
catch (UnsupportedEncodingException ex) {
ex.printStackTrace();
}
hashText = new BigInteger(1, m.digest()).toString(16);
if (hashText.length() < 64) { //must be 64 in length
int numberOfZeroes = 64 - hashText.length();
String zeroes = "";
for (int i = 0; i < numberOfZeroes; i++) {
zeroes = zeroes + "0";
}
hashText = zeroes + hashText;
}
}
catch (NoSuchAlgorithmException ex) {
ex.printStackTrace();
}
hashText = hashText.toUpperCase();
return hashText;
}
public static byte[] hex2Byte(String str) {
byte[] bytes = new byte[str.length() / 2];
for (int i = 0; i < bytes.length; i++) {
bytes[i] = (byte) Integer
.parseInt(str.substring(2 * i, 2 * i + 2), 16);
}
return bytes;
}
C# CODE (attempt)
private static string DoSpecialSha256Hash(string message, string key)
{
String hashText = null;
Console.WriteLine("Value to hash::::::::::" + message);
byte[] keyByte = hex2Byte(key);
Encoding encoder = new System.Text.UTF8Encoding();
var hashAlgo = new SHA256Managed();
var messageBytes = encoder.GetBytes(message);
var toDigest = Combine(keyByte, messageBytes);
hashText = ByteToString(hashAlgo.ComputeHash(toDigest, 0, message.Length));
if (hashText.Length < 64)
{ //must be 64 in length
int numberOfZeroes = 64 - hashText.Length;
String zeroes = "";
for (int i = 0; i < numberOfZeroes; i++)
{
zeroes = zeroes + "0";
}
hashText = zeroes + hashText;
}
hashText = hashText.ToUpper();
return hashText;
}
public static byte[] HexToByte(String hex)
{
return Enumerable.Range(0, hex.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
.ToArray();
}
private static string ByteToString(byte[] buff)
{
string sbinary = "";
for (int i = 0; i < buff.Length; i++)
{
sbinary += buff[i].ToString("X2"); // hex format
}
return (sbinary);
}
private static byte[] Combine(params byte[][] arrays)
{
byte[] rv = new byte[arrays.Sum(a => a.Length)];
int offset = 0;
foreach (byte[] array in arrays)
{
System.Buffer.BlockCopy(array, 0, rv, offset, array.Length);
offset += array.Length;
}
return rv;
}
Thanks,
I have a wordlist with ~68000 words from level 20 at 0xf.at and want to hash two words to get a hash. Then compare this hash to an existing hash until i found the two words.
I have tried it in java but I am unexpirenced and it is to slow.
import java.io.*;
public class Main {
public static void main(String[] args) throws FileNotFoundException,
IOException {
try (BufferedReader br = new BufferedReader(new FileReader("E:/Trojan/Desktop/wordlist.txt"))) {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
Hash h = new Hash();
String myHash = "cd48323bcf01557f5deadc2ec301affb";
while (line != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
}
String everything = sb.toString();
String lines[] = everything.split("\\r?\\n");
for (int j = 1; j <= 68848; j++) {
for (int i = 1; i <= 68847; i++) {
//System.out.println(i+":"+lines[i]+" "+j+":"+lines[j]);
if (h.getHash(lines[i]+lines[j], "MD5") == myHash){
System.out.println(lines[i]+lines[j]);
break;
}
}
}
}
}
}
And the md5 hash function i took from an exmaple of stackoverflow:
public class Hash {
/**
*
* #param txt, text in plain format
* #param hashType MD5 OR SHA1
* #return hash in hashType
*/
public static String getHash(String txt, String hashType) {
try {
java.security.MessageDigest md = java.security.MessageDigest.getInstance(hashType);
byte[] array = md.digest(txt.getBytes());
StringBuffer sb = new StringBuffer();
for (int i = 0; i < array.length; ++i) {
sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1,3));
}
return sb.toString();
} catch (java.security.NoSuchAlgorithmException e) {
//error action
}
return null;
}
public static String md5(String txt) {
return Hash.getHash(txt, "MD5");
}
public static String sha1(String txt) {
return Hash.getHash(txt, "SHA1");
}
}
How can I get this faster?
You create too many temporary objects inside method getHash. Try reduce. E.g.
private static final char[] HEX ={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f',};
public static String getHash(String txt, MessageDigest md) {
byte[] array = md.digest(txt.getBytes());
char[] result = new char[array.length*2];
for (int i = 0; i < array.length; ++i) {
byte b = array[i];
result[2*i] = HEX[(b&0x0f0)>>>4];
result[2*i+1] = HEX[b&0x0f];
}
return new String(result);
}
EDIT
Moreover you do not need String objects at all. You should return byte[] and use Arrays.equals method.
this is stringToHexAsciiString.
//将字符串转成ASCII十六进制的java方法
public static String stringToHexAsciiString(String value)
{
StringBuffer sbu = new StringBuffer();
char[] chars = value.toCharArray();
for (int i = 0; i < chars.length; i++)
{
sbu.append(Integer.toHexString(chars[i]));
}
return sbu.toString();
}
this is asciiToString begin
//将ASCII转成字符串的java方法
public static String asciiToString(String value)
{
StringBuffer sbu = new StringBuffer();
//System.out.println("value.length()/2 = " + value.length()/2);
byte[] chars = new byte[value.length()/2];
chars = hexStringToByte(value);
//System.out.println("chars.length = " + chars.length);
for(int i=0; i<chars.length; i++){
//sbu.append((char) Integer.parseInt(chars[i]));
byte[] change = new byte[1];
change[0] = chars[i];
//System.out.println("change[0] = " + change[0]);
sbu.append((char) chars[i]);
//System.out.println("i = " + i + " " + sbu.toString());
}
return sbu.toString();
}
public static byte[] hexStringToByte(String hexString){
if (hexString == null || hexString.equals("")) {
return null;
}
hexString = hexString.toUpperCase();
int length = hexString.length() / 2;
char[] hexChars = hexString.toCharArray();
byte[] d = new byte[length];
for (int i = 0; i < length; i++) {
int pos = i * 2;
d[i] = (byte) (charToByte(hexChars[pos]) << 4 |charToByte(hexChars[pos + 1]));
// d[i] = (byte) (hexChars[pos] << 4 |hexChars[pos + 1]);
}
return d;
}
private static byte charToByte(char c) {
return (byte) "0123456789ABCDEF".indexOf(c);
}
use test english is ok,chinese is bad.
String strAscii = Encrypter.stringToHexAsciiString("汉1232").trim();
String asciiStr = Encrypter.asciiToString("6c4931323332".toUpperCase());
System.out.println("asciiStr:"+asciiStr);
System.out.println("strAscii:"+strAscii);
asciiToString result is chinese become messy code
asciiStr:lI1232
strAscii:6c4931323332
need to 汉1232.stringToHexAsciiString result :chinese char is 2 byte,english is 1 byte。how to div chinese hex and english hex。
I don't know what's the problem in your code... or what exactly you want, this is not clear in your question.
But if you just want convert a String to Hex format then you can try the following code:
import org.apache.commons.codec.binary.Hex;
public class StringToAscii
{
public static void main( String[] args )
{
try {
String s = "汉1232";
System.out.println(s);
String hexString = new String(Hex.encodeHexString(s.getBytes("UTF-8")));
System.out.println(hexString);
String unicode = new String(Hex.decodeHex(hexString.toCharArray()));
System.out.println(unicode);
}catch (Exception e)
{
e.printStackTrace();
}
}
}
The output on my laptop is:
汉1232
e6b18931323332
汉1232