Last active
February 17, 2024 00:16
-
-
Save fazlurr/1d2adcaa5d3d9b70d141 to your computer and use it in GitHub Desktop.
RC4+ Encryptor - http://stackoverflow.com/a/12290876
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.util.Log; | |
import java.util.Arrays; | |
/** | |
* RC4+ Encryption - from Stack Overflow | |
* Stack Overflow : http://stackoverflow.com/a/12290876 | |
* Original Code : https://code.google.com/p/a9cipher/source/browse/src/com/a9development/a9cipher/RC4.java?r=1b5bdf2a70b3ef8cc9464f8a31332a2ec9f54e7a | |
*/ | |
public class RC4Plus { | |
private static final String TAG = "RC4Plus"; | |
private final byte[] S = new byte[256]; | |
private final byte[] T = new byte[256]; | |
private final int keyLength; | |
public RC4Plus(final byte[] key) { | |
if (key.length < 1 || key.length > 256) { | |
throw new IllegalArgumentException("key must be between 1 and 256 bytes"); | |
} else { | |
keyLength = key.length; | |
/** | |
* Key-scheduling algorithm (KSA) | |
* The pseudo code : | |
* for i from 0 to 255 | |
* S[i] := i | |
* endfor | |
* j := 0 | |
* for i from 0 to 255 | |
* j := (j + S[i] + key[i mod keylength]) mod 256 | |
* swap values of S[i] and S[j] | |
* endfor | |
*/ | |
for (int i = 0; i < 256; i++) { | |
S[i] = (byte) i; | |
T[i] = key[i % keyLength]; // key[i mod keylength] | |
} | |
int j = 0; | |
byte tmp; | |
for (int i = 0; i < 256; i++) { | |
j = (j + S[i] + T[i]) & 0xFF; // & 0xff is same as mod 256 | |
// Swap values | |
tmp = S[j]; | |
S[j] = S[i]; | |
S[i] = tmp; | |
} | |
} | |
} | |
/** | |
* Pseudo-random generation algorithm (PRGA) | |
* The pseudo code : | |
* i := 0 | |
* j := 0 | |
* while GeneratingOutput: | |
* i := (i + 1) mod 256 | |
* j := (j + S[i]) mod 256 | |
* swap values of S[i] and S[j] | |
* K := S[(S[i] + S[j]) mod 256] | |
* output K | |
* endwhile | |
* @param plainTextBytes bytes from plain text | |
* @return cipherText | |
*/ | |
public byte[] encrypt(final byte[] plainTextBytes) { | |
// For storing keystream, not required | |
byte[] keystreamByteArray = new byte[plainTextBytes.length]; | |
final byte[] cipherText = new byte[plainTextBytes.length]; | |
int i = 0, j = 0, k, t; | |
byte tmp; | |
for (int counter = 0; counter < plainTextBytes.length; counter++) { | |
i = (i + 1) & 0xFF; | |
j = (j + S[i]) & 0xFF; | |
// Swap values | |
tmp = S[j]; | |
S[j] = S[i]; | |
S[i] = tmp; | |
t = (S[i] + S[j]) & 0xFF; | |
k = S[t]; | |
// The S(S(i) + S(j)) is used as a byte of the key stream, K | |
cipherText[counter] = (byte) (plainTextBytes[counter] ^ k); // '^' is XOR | |
// Not required for encryption, only for showing keystream hexadecimal | |
keystreamByteArray[counter] = ((byte) k); | |
} | |
String hexadecimalKeystream = A9Utility.bytesToHex(keystreamByteArray); | |
Log.i(TAG, "Keystream in bytes : " + Arrays.toString(keystreamByteArray)); | |
Log.i(TAG, "Keystream in hexadecimal : " + hexadecimalKeystream); | |
String hexadecimalCiphertext = A9Utility.bytesToHex(cipherText); | |
Log.i(TAG, "Ciphertext in bytes : " + Arrays.toString(cipherText)); | |
Log.i(TAG, "Ciphertext in hexadecimal : " + hexadecimalCiphertext); | |
return cipherText; | |
} | |
public byte[] decrypt(final byte[] cipherText) { | |
return encrypt(cipherText); | |
} | |
} |
Got this from the source:
public static String bytesToHex(byte[] b) {
String s = "";
for (int i = 0; i < b.length; i++) {
if (i > 0 && i % 4 == 0) {
s += " ";
}
s += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1);
}
return s;
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I have error in A9Utility and log.i, please help me
String hexadecimalKeystream = A9Utility.bytesToHex(keystreamByteArray);
Log.i(TAG, "Keystream in bytes : " + Arrays.toString(keystreamByteArray));
Log.i(TAG, "Keystream in hexadecimal : " + hexadecimalKeystream);