Adobe Air Security Aspect - air

Just created an application in Adobe Air.
Customer now says he wants security on the DVD (stop DVD from being copied or serial key)
Is there any way that I can provide some form of Serial Key Protection in Adobe AIR.
I was thinking something like writing a small script with say 50 or so 'serial numbers' in some for of xml or database.
When the script is run it allows for the execution of the program if correct serial number is given else aborts proces.
Urgent request, if someone can provide an answer there is a few £'s in it for them.

I would encode some info into serials for application to test validness (some kind of checksum.) This requires several tasks:
Encode bytes into readable symbols of serial numbers. Using limited alphabet of 10 digits and 22 latin chars, we get 32 variants per symbol giving 5 bit. So, 20 symbols are worth 100 bits, that's 16 bytes and a half. The hard part is to slice original 17 bytes into 5-bit chunks (nothing really hard, really, can be solved with shifts and masks, just requires careful coding.)
Decode symbols of serial into original bytes. Using our custom alphabet tables, convert each symbol into 5 bit and glue them together in 17 bytes (again shifts, masks and careful coding :)
Define serial number contents. While possibilities are countless, it can be done simple: first few bytes are 'magic' fixed ones. If application decodes them from serial, it is valid. The rest bytes are randomly varying from serial to serial.
If we leave it this way, all our valid serials will start from the same symbols - encoded 'magic' bytes. To mix things up, I suggest using symmetrical encryption. There is library as3 crypto which provides RC4 algorithm. You can test it on demo page - choose 'Secret key' section, set encryption to RC4, and formats of key, text and cipher text to 'hex'.
Now generation of serial looks like this: take 'magic' bytes, add random ones to get 16 bytes total. Encrypt this message and convert into serial.
Program will check serial so: convert symbols into 16 bytes, decrypt them with same key, and check for 'magic' bytes to be present.
If you leave four bytes for 'magic' ones, this means one valid serial to 4 billions. For common folks, this should be enough of protection (uncommon ones will just decompile your program and shortcut the checks, so look into software like SecureSWF to prevent that.)

Related

Initialization vector - best practices (symmetric cryptography)

I would like to ask about best practices regarding a usage of an initialization vector (IV) and a key for symmetric cryptography algorithms.
I want to accept messages from a client, encrypt them and store in a backend. This will be done over a time, and there will be requests coming at a later time for pooling out the messages and return them in a readable form.
According what I know, the key can be the same during the encryption of multiple separate messages. The IV should change with every new encryption. This however, will cause problems, because every message will need a different IV for de-cryption at a later time.
I’d like to know if this is the best way of doing it. Is there any way to avoid storing IV with every message, which would simplify entire process of working with encryption/decryption?
IV selection is a bit complicated because the exact requirements depend on the mode of operation. There are some general rules, however:
You can't go wrong¹ with a random IV, except when using shorter IVs in modes that allow this.
Never use the same IV with the same key.
If you only ever encrypt a single message with a given key, the choice of IV doesn't matter².
Choose the IV independently of the data to encrypt.
Never use ECB.
Of the most common specific modes of operation:
CBC requires the IV to be generated uniformly at random. Do not use a counter as IV for CBC. Furthermore, if you're encrypting some data that contains parts that you receive from a third party, don't reveal the IV until you've fully received the data, .
CTR uses the IV as the initial value of a counter which is incremented for every block, not for every message, and the counter value needs to be unique for every block. A block is 16 bytes for all modern symmetric ciphers (including AES, regardless of the key size). So for CTR, if you encrypt a 3-block message (33 to 48 bytes) with 0 as the IV, the next message must start with IV=3 (or larger), not IV=1.
Modern modes such as Chacha20, GCM, CCM, SIV, etc. use a nonce as their IV. When a mode is described as using a nonce rather than an IV, this means that the only requirement is that the IV is never reused with the same key. It doesn't have to be random.
When encrypting data in a database, it is in general not safe to use the row ID (or a value derived from it) as IV. Using the row ID is safe only if the row is never updated or removed, because otherwise the second time data is stored using the same ID, it would repeat the IV. An adversary who sees two different messages encrypted with the same key and IV may well be able to decrypt both messages (the details depend on the mode and on how much the attacker can guess about the message content; note that even weak guesses such as “it's printable UTF-8” may suffice).
Unless you have a very good reason to do otherwise (just saving a few bytes per row does not count as a very good reason) and a cryptographer has reviewed the specific way in which you are storing and retrieving the data:
Use an authenticated encryption mode such as GCM, CCM, SIV or Chacha20+Poly1305.
If you can store a counter somewhere and make sure that it's never reset as long as you keep using the same encryption key, then each time you encrypt a message:
Increment the counter.
Use the new value of the counter as the nonce for the authenticated encryption.
The reason to increment the counter first is that if the process is interrupted, it will lead to a skipped counter value, which is not a problem. If step 2 was done without step 1, it would lead to repeating a nonce, which is bad. With this scheme, you can shave a few bytes off the nonce length if the mode allows it, as long as the length is large enough for the number of messages that you'll ever encrypt.
If you don't have such a counter, then use the maximum nonce length and generate a random counter. The reason to use the maximum nonce length is that due to the birthday paradox, a random n-bit nonce is expected to repeat when the number of messages approaches 2n/2.
In either case, you need to store the nonce in the row.
¹ Assuming that everything is implemented correctly, e.g. random values need to be generated with a random generator that is appropriate for cryptography.
² As long as it isn't chosen in a way that depends on the key.

Hash Function for 2D Barcode Data

I am writing a string of about 120 characters to a 2D barcode. Along with other text, the string contains a unique ticket number. I want to ensure that someone doesn't generate counterfeit tickets by reading the 2D barcode and generation their own barcoded tickets.
I would like to hash the string and append the hash value to what gets embedded in the barcode. That way I can compare the two on reading and see if the data had been tampered with. I have seen several hash function that return 64 bytes and up but the more characters you embed in a 2D barcode the bigger the barcode image becomes. I would like an algorithm that returns a fairly small value. It would also be nice if I could provide the function my own key. Collision is not that big of a deal. This isn't any kind of national security application.
Any suggestions?
Use any standard hash function. Take the 120-character string; append your own secret value; feed it into SHA-1 or MD5 or whatever hash function you have handy or feel like implementing; then just take the first however-many bits you want and use that as your value. (If you need ASCII characters, then I suggest that you take groups of 6 bits and use a base-64 encoding.)
If the hash you're using is any good (as, e.g., MD5 and SHA-1 are; MD5 shouldn't be used for serious cryptographic algorithms these days but it sounds like it's good enough for your needs) then any set of bits from it will be "good enough" in the sense that no other function producing that many bits will be much better.
(Warning: For serious cryptographic use, you should be a little more careful. Look at, e.g., http://en.wikipedia.org/wiki/HMAC for more information. From your description, I do not believe you need to worry about such things.)

Why are an integers bytes stored backwards? Does this apply to headers only?

I'm currently trying to decipher WAV files. From headers to the PCM data.
I've found a PDF (http://www.tdt.com/T2Support/technical_notes/tn0132.pdf) detailing the anatomy of a WAV file, and I've been able to extract and make sense of the appropriate header data using Ghex2. But my questions are:
Why are the integers bytes stored backwards? I.e. dec. 20 is stored as 0x14000000 instead of 0x00000014.
Are the integers of the PCM data also stored backwards?
WAV files are little-endian (least significant bytes first) because the format originated for operating systems running on intel processor based machines which use the little endian format to store numbers.
If you think about it kind of makes sense because if you want to cast a long integer to a short one or even a character the starting address remains the same you just look at less bytes.
Consequently, for 16 bit encoding upwards, little-endian format will be used for the PCM as well. This is quite handy since you will be able to pull them in as integers. don't forget they will be stored as two's complement signed integers if they are 16 bit, but not if they are 8 bit. (see http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html for more detail)
"Backwards" is subjective. Some machines are big-endian, others are little-endian. In byte-oriented contexts like file formats and network protocols, the order is arbitrary. Some formats like to specify big- or little-endian, others like to be flexible and accept either form, with a flag indicating which is in use.
Looks like WAV files just like little-endian.

How long should SQL email fields be? [duplicate]

This question already has answers here:
What is the optimal length for an email address in a database?
(9 answers)
Closed 9 years ago.
I recognize that an email address can basically be indefinitely long so any size I impose on my varchar email address field is going to be arbitrary. However, I was wondering what the "standard" is? How long do you guys make it? (same question for Name field...)
update: Apparently the max length for an email address is 320 (<=64 name part, <= 255 domain). Do you use this?
The theoretical limit is really long but do you really need worry about these long Email addresses? If someone can't login with a 100-char Email, do you really care? We actually prefer they can't.
Some statistical data may shed some light on the issue. We analyzed a database with over 10 million Email addresses. These addresses are not confirmed so there are invalid ones. Here are some interesting facts,
The longest valid one is 89.
There are hundreds longer ones up to the limit of our column (255) but they are apparently fake by visual inspection.
The peak of the length distribution is at 19.
There isn't long tail. Everything falls off sharply after 38.
We cleaned up the DB by throwing away anything longer than 40. The good news is that no one has complained but the bad news is not many records got cleaned out.
I've in the past just done 255 because that's the so-ingrained standard of short but not too short input. That, and I'm a creature of habit.
However, since the max is 319, I'd do nvarchar(320) on the column. Gotta remember the #!
nvarchar won't use the space that you don't need, so if you only have a 20 character email address, it will only take up 20 bytes. This is in contrast to a nchar which will always take up its maximum (it right-pads the value with spaces).
I'd also use nvarchar in lieu of varchar since it's Unicode. Given the volatility of email addresses, this is definitely the way to go.
The following email address is only 94 characters:
i.have.a.really.long.name.like.seetharam.krishnapillai#AReallyLongCompanyNameOfSomeKind.com.au
Would an organisation actually give you an email that long?
If they were stupid enough to, would you actually use an email address like that?
Would anyone? Of course not. Too long to type and too hard to remember.
Even a 92-year-old technophobe would figure out how to sign up for a nice short gmail address, and just use that, rather than type this into your registration page.
Disk space probably isn't an issue, but there are at least two problems with allowing user input fields to be many times longer than they need to be:
Displaying them could mess up your UI (at best they will be cut off, at worst they push your containers and margins around)
Malicious users can do things with them you can't anticipate (like those cases where hackers used a free online API to store a bunch of data)
I like 50 chars:
123456789.123456789.123456789#1234567890123456.com
If one user in a million has to use their other email address to use my app, so be it.
(Statistics show that no-one actually enters more than about 40 chars for email address, see e.g.: ZZ Coder's answer https://stackoverflow.com/a/1297352/87861)
According to this text, based on the proper RFC documents, it's not 320 but 254:
http://www.eph.co.uk/resources/email-address-length-faq/
Edit:
Using WayBack Machine:
https://web.archive.org/web/20120222213813/http://www.eph.co.uk/resources/email-address-length-faq/
What is the maximum length of an email address?
254 characters
There appears to be some confusion over the maximum valid email
address size. Most people believe it to be 320 characters (64
characters for the username + 255 characters for the domain + 1
character for the # symbol). Other sources suggest 129 (64 + 1 + 64)
or 384 (128+1+255, assuming the username doubles in length in the
future).
This confusion means you should heed the 'robustness principle'
("developers should carefully write software that adheres closely to
extant RFCs but accept and parse input from peers that might not be
consistent with those RFCs." - Wikipedia) when writing software that
deals with email addresses. Furthermore, some software may be crippled
by naive assumptions, e.g. thinking that 50 characters is adequate
(examples). Your 200 character email address may be technically valid
but that will not help you if most websites or applications reject it.
The actual maximum email length is currently 254 characters:
"The original version of RFC 3696 did indeed say 320 was the maximum
length, but John Klensin (ICANN) subsequently accepted this was
wrong."
"This arises from the simple arithmetic of maximum length of a domain
(255 characters) + maximum length of a mailbox (64 characters) + the #
symbol = 320 characters. Wrong. This canard is actually documented in
the original version of RFC3696. It was corrected in the errata.
There's actually a restriction from RFC5321 on the path element of an
SMTP transaction of 256 characters. But this includes angled brackets
around the email address, so the maximum length of an email address is
254 characters." - Dominic Sayers
I use varchar(64) i do not think anyone could have longer email
If you're really being pendantic about it, make a username varchar(60), domain varchar(255). Then you can do ridiculous statistics on domain usage that is slightly faster than doing it as a single field. If you're feeling really gun-ho about optimization, that will also make your SMTP server able to send out emails with fewer connections / better batching.
RFC 5321 (the current SMTP spec, obsoletes RFC2821) states:
4.5.3.1.1. Local-part
The maximum total length of a user
name or other local-part is 64
octets.
4.5.3.1.2. Domain
The maximum total length of a
domain name or number is 255 octets.
This pertains to just localpart#domain, for a total of 320 ASCII (7-bit) characters.
If you plan to normalize your data, perhaps by splitting the localpart and domain into separate fields, additional things to keep in mind:
A technique known as VERP may result in full-length localparts for automatically generated mail (may not be relevant to your use case)
domains are case insensitive; recommend lowercasing the domain portion
localparts are case sensitive; user#domain.com and USER#domain.com are technically different addresses per the specs, although the policy at the domain.com may be to treat the two addresses as equivalent. It's best to restrict localpart case folding to domains that are known to do this.
For email, regardless of the spec, I virtually always go with 512 (nvarchar). Names and surnames are similar.
Really, you need to look at how much you care about having a little extra data. For me, mostly, it's not a worry, so I'll err on the conservative side. But if you've decided, through logically and accurate means, that you'll need to conserve space, then do so. But in general, be conservative with field sizes, and life shall be good.
Note that probably not all email clients support the RFC, so regardless of what it says, you may encounter different things in the wild.

[My]SQL VARCHAR Size and Null-Termination

Disclaimer: I'm very new to SQL and databases in general.
I need to create a field that will store a maximum of 32 characters of text data. Does "VARCHAR(32)" mean that I have exactly 32 characters for my data? Do I need to reserve an extra character for null-termination?
I conducted a simple test and it seems that this is a WYSIWYG buffer. However, I wanted to get a concrete answer from people who actually know what they're doing.
I have a C[++] background, so this question is raising alarm bells in my head.
Yes, you have 32 characters at your disposal. SQL does not concern itself with nul terminated strings like some programming languages do.
Your VARCHAR specification size is the max size of your data, so in this case, 32 characters. However, VARCHARS are a dynamic field, so the actual physical storage used is only the size of your data, plus one or two bytes.
If you put a 10-character string into a VARCHAR(32), the physical storage will be 11 or 12 bytes (the manual will tell you the exact formula).
However, when MySQL is dealing with result sets (ie. after a SELECT), 32 bytes will be allocated in memory for that field for every record.