I wrote server and client and I would like to send some file which will be encrypted. So I have to operate on bits, not bytes, because my cryptography metod is like that: I send my file in parts of about 8 bits and I add to them some specific MAC. (its: winnowing and Chaffing metod)
In my program I read file into byte array. But I need byte to bits to add MAC adress to each part of file and send them in parts.
My question is:
Is there any posibility to operate on bits in Java, or if not how would you solve this problem?
Why dont you just use SSL or TLS? Or any other built in security protocol. It seems weird to re-invent the wheel here.
Often, proprietary encryption systems are less secure than well known ones, because they have not been subject to public scrutiny.
The fact that nobody knows about it does not make it more secure. "Security by Obscurity" is never the best practice.
I really don't think your problem will be solved by converting bytes to bits, but here's how you can do it.
static boolean[] byteToBits(byte b) {
boolean[] bits = new boolean[8];
for (int idx = 0; idx < 8; ++idx)
bits[idx] = ((b >> idx) & 1) == 1;
return bits;
}
Related
I've run into mind twisting bafflement after putting my hands into an old legacy project. The project consists of a Java application and a c++ application, which communicate with sockets. Both applications are designed to work on cross platform environments, so I'd be happy to keep the code as universal as possible.
I ended up rewriting parts of the communication logic, since the previous implementation had some issues with foreign characters. Now I ran into a problem with endianness, which I hope someone could spell out for me.
The Java software writes messages to socket with OutputStreamWriter, using UTF-16LE encoding, as follows.
OutputStream out = _socket.getOutputStream();
outputWriter = new OutputStreamWriter(new BufferedOutputStream(out), "UTF-16LE");
// ... create msg
outputWriter.write(msg, 0, msg.length());
outputWriter.flush();
The c++ program receives the message character by character as follows:
char buf[1];
std::queue<char> q;
std::u16string recUtf16Msg;
do {
int iResult = recv(socket, buf, 1, 0);
if (iResult <= 0)
break; // Error or EOS
for (int i = 0; i < iResult; i++) {
q.push(buf[i]);
}
while (q.size() >= 2) {
char firstByte = q.front();
q.pop();
char secondByte = q.front();
q.pop();
char16_t utf16char = (firstByte << (sizeof(char) * CHAR_BIT)) ^
(0x00ff & secondByte);
// Change endianness, if necessary
utf16char = ntohs(utf16char);
recUtf16Msg.push_back(utf16char);
}
// ... end of message check removed for clarity
} while (true);
Now the issue which I'm really facing is that the code above actually works, but I'm not really sure why. The c++ side is written to receive messages which use network byte order (big endian) but it seems that java is sending the data using little endian encoding.
On c++ side we even use ntons-function to change endianness to the one desired by host machine. According to specification I understand that hton is supposed to do swap endianness if host platform uses little endian byte order. However ntonhs actually swaps the endianness of the received small endian characters, which ends up as big endian and the software works flawlessly.
Maybe someone can point out what exactly is happening? Do I accidentally switch bytes already to when creating utf16char? Why htons makes everything work, while it seems to act exactly opposite to the documentation? To compile I'm using Clang with libc++.
I left out parts of the code for clarity, but you should get the general idea. Also, I'm aware that using queue and dynamic array may not be the most effective way of handling data, but it's clean and performs well enough for this purpose.
I'm working on an application that's supposed to read and process flat files. These files don't always use a consistent encoding for every field in a record, so it was decided that we should read/write bytes and avoid the necessary decoding/encoding of turning them into Strings.
However, a lot of these fields are simple integers, and I need to validate them (test that they are really integers and in a certain range). I need a function that receives a byte[] and turns that into an int. I'm assuming all the digits are plain ASCII.
I know I could do this by first turning the byte[] into a CharBuffer, decoding to ISO-8859-1 or UTF-8, and then calling Integer.parseInt() but that seems like a lot of overhead and performance is important.
So, basically what I need is a Java equivalent of atoi(). I would prefer an API function (including 3rd party APIs). Also, the function should report errors in some way.
As a side note, I'm having the same issue with fields representing date/time (these are more rare though). It would be great if someone could mention some fast C-like library for Java.
while i can not give you a ready java solution i want to point you onto interesting (c) code for you to read: the author of qmail has a small function to quickly parse unsigned longs from a byte array scan_ulong, you can find lots of incarnations of that function all over the web:
unsigned int scan_ulong(register const char *s,register unsigned long *u)
{
register unsigned int pos = 0;
register unsigned long result = 0;
register unsigned long c;
while ((c = (unsigned long) (unsigned char) (s[pos] - '0')) < 10) {
result = result * 10 + c;
++pos;
}
*u = result;
return pos;
}
(taken from here: https://github.com/jordansissel/djbdnsplus/blob/master/scan_ulong.c )
that code should translate pretty smoothly to java.
The atoi function from the C library is an incredibly dull piece of code: you can translate it to Java in five minutes or less. If you must avoid writing your own, you could use the String(byte\[\] buf, int offset,int length) constructor to make Java string bypassing CharBuffer, and parse it to complete the conversion.
I am looking for a simple and FAST algorithm to encrypt/decrypt a string (length is about 128 bytes) with a password.
Any good algorithms?
ADDED: Custom algorithm is absolutely OK. Less memory it take - better it is (for my case). No extra classes - perfect.
AES Algorithm : Implementation
AES is a federal standard for
private-key or symmetric cryptography.
It supports combinations of key and
block sizes of 128, 192, and 256.
How about IDEA - International Data
Encryption Algorithm ?
IDEA is the name of the patented and
universally applicable block
encryption algorithm, which permits
the effective protection of
transmitted and stored data against
unauthorized access by third parties.
See for the implementation : How to implement IDEA?
AES or 3DES are pretty "standard" symmetrical key encryptions. Blowfish is another.
Check http://java.sun.com/developer/technicalArticles/Security/AES/AES_v1.html for using AES with Java, for instance.
Side note: If this is intended for securing something like passwords, you should really use a one-way hashing method instead (like MD5 or similar). Unless you absolutely have to be able to decrypt the text, one-way hashing is much safer. When, for instance, storing passwords in a database you would hash the password (with something like MD5) and store it. Validating a login is then done by hashing the user input and comparing it with the hashed value stored in the database.
See Java Crypto! for Encryption and Decryption
There is the Tiny Encryption Algorithm ( http://en.wikipedia.org/wiki/XXTEA ).
It's pretty simple and fast (for an encryption algorithm) and there are Java implementations.
Here is a simple encryption/decryption method. It is pretty weak, so I present it for, say education purpose:
public static String encDec(String input, String password) {
byte[] in = input.getBytes();
byte[] key = password.getBytes();
byte[] result = new byte[in.length];
int k = 0;
for (int i = 0; i < in.length; i++) {
result[i] = (byte)(in[i] ^ key[k]);
k++;
if (k == key.length)
k=0;
}
return new String(result);
}
It simply xors the bytes of a phrase with the bytes of a password. The same method can be used to encrypt and decrypt. Not a big challenge for a crypto analyst, by the way, but an easy start if you just need to obfuscate some data.
To make it a slightly better: don't pass a password String but a byte array with random values. But you wanted a method with a password, that's why I've implemented it that way ;)
I have to send a short string from ANSI C application to Java application through a socket - already done. Because its important data I have to encrypt it using password like "abc123". How should I do it in the simpliest way?
By "socket" I assume you mean a TCP/IP connection. In that case you should consider using Secure Sockets Layer (SSL). SSL pretty much solves most of the security problems associated with sending data across the wire. The only thing you need to work out is how to distribute keys to each end of the pipe.
I strongly recommend that you don't roll your own system. Crypto is hard to get right so use an existing, well tested implementation.
If you're talking about a Unix domain socket then you probably don't need to bother with encryption since domain sockets are just inter-process pipes.
As mentioned it depends very much on how secure you want this to be, the sensible answer is to find a Java and C implementation of the same cryptosystem and use those.
If you are willing to accept the lower security that usually comes with home brewing these things which I assume you are by the "simplest way" in your question and assuming both the source and runtime for both ends are secure. I.E. you only need to worry about the data in transit being intercepted. You could just use whatever password you desire as a seed for a pseudo random number generator (remainder of dividing a large prime by the byte index or similar) and XOR the bytes of data with the random numbers generated. Not the most secure but would be very quick to implement.
uint8_t encrypt(uint8_t iData, size_t iPos) {
// Super large prime, our 'password', best kept super secret
const uint64_t iSeed = 32416190071;
// Mostly to stop divide by zero
// Also starting in the obvious place gives more info on the prime
const size_t iOffset = 10;
uint8_t iPad = iSeed % (iPos + iOffset);
return iPad^iData;
}
Char encrypt(char ch) {
Return (ch ^0x55);
}
I am currently trying to modify an existing GWT-Ext application, that is using plain text passwords in its MySql database.
My plan was to use md5 hashes, as the existing passwords can be easily altered with the MySql function and I was expecting to find an easy solution for the GWT-Ext side as well. But as I found out, java.security is not supported by GWT and there doesn't seem to be any other implementation that can be used to change the password string to a md5 hash on client side.
Only "solution" I found so far, is to re implement a md5 method via JSNI as described here:
http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/ad09475a9944c9f8
There is an existing user extension for Ext-JS, but I couldn't find anything for GWT-Ext:
http://extjs.com/forum/showthread.php?p=133516
Does anybody know a more elegant/simple way to solve this problem? Maybe I should use something else instead of md5 to make sure the passwords are encrypted?
Cheers
Frank
Personally, I would say you're doing it wrong. I wouldn't hash a password on the client side (which is what GWT is). If you hash your password, you will undoubtedly want to salt it, otherwise you will be susceptible to rainbow attacks. If you hash + salt it on the client side, your salt will be accessible to your users.
If I were you, I would hash + salt your password on the server side. This will allow you to use your standard Java code to perform your MD5 hash.
My 2 cents.
-JP
Another idea that may fit your need is something called zero knowledge auth. (Ie. the server never needs to know the user's plain text password.)
Basically, when setting the initial password, the client hashes the user's password N times (where N is a largish number like 1000), and then sends that final hash to the server along with N. The server stores the hash and N.
Later, when the user wants to authenticate, the server tells the client N-1, and the client hashes the password the user types N-1 times and sends that to the server. The server does 1 more hash on the received hash, and (hopefully) gets the stored hash. The server then stores the N-1 hash and N-1 number.
Each time the user authenticates, the server decrements the stored N and saves the previous hash.
When N gets down to 0, the user must choose and set a new password.
The server must ensure that it never asks for the same iteration, otherwise it is vulnerable to a replay. You can't really enforce that condition from the client side because the client (especially a browser) can't reliably keep track of the last N.
You can use gwt-crypto to generate SHA-1 hashes on the client side using:
String getSHA1for(String text) {
SHA1Digest sd = new SHA1Digest();
byte[] bs = text.getBytes();
sd.update(bs, 0, bs.length);
byte[] result = new byte[20];
sd.doFinal(result, 0);
return byteArrayToHexString(result);
}
String byteArrayToHexString(final byte[] b) {
final StringBuffer sb = new StringBuffer(b.length * 2);
for (int i = 0, len = b.length; i < len; i++) {
int v = b[i] & 0xff;
if (v < 16) sb.append('0');
sb.append(Integer.toHexString(v));
}
return sb.toString();
}
You should never use an md5 or other hash functions for password encryption. See http://codahale.com/how-to-safely-store-a-password/
You want gwt-crypto. It includes lots of standard crypto stuff.