I'm a beginner java programmer. I'm working on an application that decrypts some data.
The decryption key is hardcoded into the software and thus can be seen by analyzing the bytecode.
I know that reverse engineering cannot be prevented entirely so what I'm trying to do is to make the process as hard as possible.
My idea is not to directly put the key into my code but have it go through some kind of transformation.
For example, I could write -
private static final byte[] HC256A = Hex
.decode("8589075b0df3f6d82fc0c5425179b6a6"
+ "3465f053f2891f808b24744e18480b72"
+ "ec2792cdbf4dcfeb7769bf8dfa14aee4"
+ "7b4c50e8eaf3a9c8f506016c81697e32");
This way someone looking at the bytecode can't read it straight away. But will have to follow the logic and apply transformations to it, which won't be that much easier at byte level.
So what do you guys think? Is this useful? What could be the be the best transformation other than hex decoding?
Are there any other methods available to protect hardcoded decryption keys?
Thanks for all your suggestions.
Right way to attack such obfuscation (especially in bytecode languages) is to attach debugger to the place to which the key is passed (if debugging is not possible, start analyzing code from that place). This way the attacker doesn't need to look for the key at all and he doesn't care how obfuscated the key is. So you need to re-think your design.
If you only want to protect from the amateur lurkers, then splitting the key and XORing it's parts (possibly with different keys), would be enough. One more trick - derive the key from text constants already present in the code (such as application name). This makes the key less obvious than splitting or XORing.
Don't code the key into the source code at all. Keep it separate, ship it separately, e.g. in a Java keystore, and only to customers/sites/clients you trust, and put some legalese in the licence that places the onus on them if they leak the keystore.
Faced with a similar problem (in c) I went with single use XOR pads. This is good because it looks like garbage... if you get really clever you can snoop for that (incorrect) key in use. I would avoid anything that injects human readable strings as those will invariably draw attention to that bit of code.
Related
We have an online key-in interface, and are support credit card swipe capability. In the industry today, the card reader should encrypt the information before encoding it to ASCII, and then it is up to server-side to decrypt. (so the local machine never sees the card info)
I am using MagTek card reader in keyboard emulation mode, and have it with the ANSI standard key injected for testing purposes. Once decode & decryption successful, we'll get our own key registered with MagTek and order some production-use readers.
I know this decryption has been implemented before in C# and other languages, but need something in Java, or perhaps some other CLI-accessible program that can be included with a Java webapp. I am about to proceed with porting some C# code to Java, but first need to set up a C# environment. (I've never done this before.)
Once I've ensured the C# version works well, then I know I can eliminate any errors during porting with my usual debugging techniques.
Before I go through all of this, if there is an easier way please let me know. I would think this has already been done in Java, but perhaps not...
Partial answer, CW for anyone to add to.
First, it's not clear (to me) if you want to run on PCs or similar where the swipe devices are, possibly downloaded (like applet or webstart), or to just get the encrypted swipe data (in a webform?) and send it to your server to decrypt. I suggest the latter makes PCI DSS compliance easier.
Java crypto certainly does 3DES, under the name DESede (case-insensitive, like all JCA Cipher names). One slightly unobvious point: the implementation in SunJCE only handles full 24-byte keys. DUKPT uses "2-key 3DES", so you need to copy "left" to bytes 0-7, "right" to 8-15, and "left" again to 16-23. If you use BouncyCastle (as my shop does) it can take a 16-byte key and do the copy internally, which is slightly more convenient. (A symmetric key in Java is a byte array in a thin wrapper class, usually javax.crypto.spec.SecretKeySpec.)
If you're not familiar with Java crypto in general, the pattern is that you obtain an "instance" of a particular algorithm or mode from a "provider" (you can specify one or let Java choose automatically; several are builtin and more can be added, like "bcprov" from www.BouncyCastle.org) using a generic API class Cipher, Signature, MessageDigest, etc, then initialize that instance with needed parameters (such as key or IV, and direction), then call methods to take input data and return output either in separate (possibly multiple) steps or in a simple combined doFinal (which is fine for your case). The JCA manual http://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html#Cipher and javadoc for the applicable API class javax.crypto.Cipher (at http://docs.oracle.com/javase/8/docs/api/index.html and also automatically displayed in leading IDEs) has quite full details on this.
I haven't seen any open/free implementation of DUKPT but that doesn't prove there isn't one. It is straightforward, though a bit tedious, to just code the steps from X9.24, if no one offers better.
Good rule of thumb: If you need encryption, don't do it yourself. You'll get it wrong!
So far so good. I was looking at Jasypt for that reason. it claims to do all the complicated stuff for you, without you needing to understand it. It offers you a class with the trustworthy name StrongPasswordEncryptor:
Utility class for easily performing high-strength password digesting and checking.
Still I wanted to know more about what it does, before I trust my users passwords to it. As it claims in the API:
This class internally holds a StandardStringDigester configured this way:
Algorithm: SHA-256.
Salt size: 16 bytes.
Iterations: 100000.
And that's were my basic knowledge on that topic tells me: That's not how you should do it!
In fact it looks to me like a naive approach. Take SHA, because MD5 is not secure any more, but better take one with a bigger number, because bigger is better there. But multiple bytes of salt in there and then run it lots of times to be harder to crack.
Why do I think that is bad? SHA is basically designed to be an elaborated kind of check digit. It is meant to be fast. That is the opposite of what you want of a password hashing algorithm. You want those to be cost expansive even on hardware designed to be fast on them. In fact there is a lot of discourse on the web who good bcrypt and PBKDF2 lack some important requirements and if scrpyt should be used instead. Look at these stackexchange questions to get an idea: https://security.stackexchange.com/questions/4781/do-any-security-experts-recommend-bcrypt-for-password-storage, SHA512 vs. Blowfish and Bcrypt
To give a quote from http://www.jasypt.org/howtoencryptuserpasswords.html
In most cases, both MD5 or SHA-1 will be adequate choices for password digesting, although applying these algorithms will not be enough, as we will see later on.
I'm passionally disagreeing in that point, because of the reasons above.
Am I missing something here, or is Jasypt really selling me a fundamentally flawed algorithm under the name StrongPasswordEncryptor? Because if it does, I don't want to trust that library with my most sensitive data.
I know, I could just decide to simply not use it, but because of my rule of thumb I mentioned at the beginning, I'd like to have my evaluation checked by people with understanding in password encryption.
sorry about the last question. (I hate google traductor).
Im working in a MMO (Masive Multiplayer Online) game, but i see many times some server emulator for example for Lineage 2 or Aion of NCSoft.
My game is C++ Based and the server emulator is in Java.
Then, i guess URL Encode method because can encode and decode in both programing languages but is easy to decode.
Another idea is create packages like uint values 0x00000 + Action Parameters(URLEncoded) but i think isn't a good idea because is easy to decode.
Another one, is create a simple encryption method remplace characters for another characters.
An Example:
To encode: Hello
Encoded: 72S/101NK&108-ASK+108P$I111?TRY
Pretty simple to decode, split for no numeric characters and delete it. Is an ASCII simple encode per each character but incrence the package size alot.
Someone know an encode method than can be decoded in C++ and Java?
Thanks you for read.
Have nice day, Marcos.
I assume you require a means to encrypt and decrypt data (I believe these are the terms you're looking for, rather than encode/decode). Or is it code obfuscation you're looking for?
If this is about encryption/decryption, there are plenty of algorithms that have implementations in numerous programming languages. For the love of goodness, don't use something like URL encoding or a simple substituting cypher, since these are trivially easy to break.
Where encryption and security are concerned, the users of your game rely on the developer to make robust, industry-standard choices that protect their personal information and the time they invest in their character build. So I suggest you either seriously read up on the concepts of encryption and authentication and then make a solid choice, or have this handled by an expert in the field.
Don't roll your own here, as that's usually the best way to make something easily hackable. Encryption standards like AES, secured protocols like SSL and TLS, and authentication based on certificates are all well-established, thoroughly tested through years of use and properly documented. It probably matters little if there's a difference in the language used for client and server, but that's actually the case for any network communication if there's proper abstraction.
I want to send secure data(strings) from a client to a server. This is what i think i want to do:
Turn the string into a byte array
"scramble" the bytes by putting them out of order in a specific way
Serialize array of bytes inside of a class
send the Encrypted and Serialized class to the server
then the server would:
Deserialize the class
get the bytes for the string
put the bytes in the right order
make a string out of the bytes
would this be a good way to Manually Encrypt data? Is this secure? Is it even worth the time trying to make a manual encrypter?
It sounds like you're trying to roll your own symmetric encryption scheme, using a fixed key (the "specific way" you're scrambling the bytes) known to both sides. There's no advantage to doing this over simply using a build-in encryption scheme with a known key, and substantial potential disadvantages. It takes just a small implementation mistake to create an opening that malign users can exploit.
Unless you do encryption for a living, you can't do better than what's out there, known, and proven in the field (AES is a good start). If security is important to you, don't try. If you want to experiment as a hobby, though, have fun.
Would this be a way to encrypt the data?
If you're just "scrambling" the data, no. It would be "trivially possible" to reconstruct the plaintext if it's just being scrambled. (This means the first time someone wants to read the data, they probably will, but if they're not trying too hard, they won't stumble across it by accident.)
On the other hand, if you're then running a "real" encryption algorithm over it, the scrambling adds a negligible degree of difficulty to the decryption, but you're relying upon a simple scrambling being sufficient to slow down someone who's just cracked the "real" encryption, which seems unlikely to be worthwhile.
You'd probably do far better to stick with a well-tested encryption mechanism designed by someone who does math with very large prime numbers for a living. Java's encryption framework lets you fairly easily implement a public/private key system, or a double-blind key exchange system; for example, you can just use HTTP-SSL for data exchange without much set-up on your part.
No, jumbling is not very goood. For a simple scheme you can build on check out the XOR operator.
I looking for a program or library in Java capable of finding non-random properties of a byte sequence. Something when given a huge file, runs some statistical tests and reports if the data show any regularities.
I know three such programs, but not in Java. I tried all of them, but they don't really seem to work for me (which is quite surprising as one of them is by NIST). The oldest of them, diehard, works fine, but it's a bit hard to use.
As some of the commenters have stated, this is really an expert mathematics problem. The simplest explanation I could find for you is:
Run Tests for Non-randomness
Autocorrelation
It's interesting, but as it uses 'heads or tails' to simplify its example, you'll find you need to go much deeper to apply the same theory to encryption / cryptography etc - but it's a good start.
Another approach would be using Fuzzy logic. You can extract fuzzy associative rules from sets of data. Those rules are basically implications in the form:
if A then B, interpreted for example "if 01101 (is present) then 1111 (will follow)"
Googling "fuzzy data mining"/"extracting fuzzy associative rules" should yield you more than enough results.
Your problem domain is quite huge, actually, since this is what data/text mining is all about. That, and statistical & combinatorial analysis, just to name a few.
About a program that does that - take a look at this.
Not so much an answer to your question but to your comment that "any observable pattern is bad". Which got me thinking that randomness wasn't the problem but rather observable patterns, and to tackle this problem surely you need observers. So, in short, just set up a website and crowdsource it.
Some examples of this technique applied to colour naming: http://blog.xkcd.com/2010/05/03/color-survey-results/ and http://www.hpl.hp.com/personal/Nathan_Moroney/color-name-hpl.html