2

Does anyone know which algorithm Progress 10.1C uses in the Encode Function?

I found this: http://knowledgebase.progress.com/articles/Article/21685

The Progress 4GL ENCODE function uses a CRC-16 algorithm to generate its encoded output.

Progress 4GL:

ENCODE("Test").

gives as output "LkwidblanjsipkJC"

But for example on http://www.nitrxgen.net/hashgen/ with Password "Test", I never get the Result as from Progress..

Any Ideas? :)

RaphaelH
  • 2,144
  • 2
  • 30
  • 43
  • Looking for the right algorithm, to get the same Result as in Progress.. Authentication stuff... :) – RaphaelH Aug 01 '12 at 07:47
  • Yeah, I see what you're saying now. Good luck with that - guess you'll have to reverse engineer it or call out to some standalone Progress executable to generate it. – Abe Voelker Aug 02 '12 at 16:46

5 Answers5

6

I've made the algorithm available on https://github.com/pvginkel/ProgressEncode.

Pieter van Ginkel
  • 29,160
  • 8
  • 71
  • 111
  • 1
    Huge thanks to Pieter, I'm not sure how you were able to come up with the algorithm but because you did I can now integrate our other apps with our progress application. For those looking for a PHP implementation I have posted one at https://github.com/ExchangeCore/progressencode – Joe Meyer Jan 06 '15 at 14:59
2

I needed this function in Java. So I ported Pieter's C# code (https://github.com/pvginkel/ProgressEncode) to Java. At least all test cases passed. Enjoy! :)

public class ProgressEncode {

    static int[] table = { 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0,
            0x0280, 0xC241, 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1,
            0xC481, 0x0440, 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1,
            0xCE81, 0x0E40, 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0,
            0x0880, 0xC841, 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1,
            0xDA81, 0x1A40, 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0,
            0x1C80, 0xDC41, 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0,
            0x1680, 0xD641, 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1,
            0xD081, 0x1040, 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1,
            0xF281, 0x3240, 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0,
            0x3480, 0xF441, 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0,
            0x3E80, 0xFE41, 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1,
            0xF881, 0x3840, 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0,
            0x2A80, 0xEA41, 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1,
            0xEC81, 0x2C40, 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1,
            0xE681, 0x2640, 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0,
            0x2080, 0xE041, 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1,
            0xA281, 0x6240, 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0,
            0x6480, 0xA441, 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0,
            0x6E80, 0xAE41, 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1,
            0xA881, 0x6840, 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0,
            0x7A80, 0xBA41, 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1,
            0xBC81, 0x7C40, 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1,
            0xB681, 0x7640, 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0,
            0x7080, 0xB041, 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0,
            0x5280, 0x9241, 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1,
            0x9481, 0x5440, 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1,
            0x9E81, 0x5E40, 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0,
            0x5880, 0x9841, 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1,
            0x8A81, 0x4A40, 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0,
            0x4C80, 0x8C41, 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0,
            0x4680, 0x8641, 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1,
            0x8081, 0x4040 };

    public static byte[] Encode(byte[] input) {
        if (input == null)
            return null;
        byte[] scratch = new byte[16];
        int hash = 17;
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < input.length; j++)
                scratch[15 - (j % 16)] ^= input[j];
            for (int j = 0; j < 16; j += 2) {
                hash = Hash(scratch, hash);
                scratch[j] = (byte) (hash & 0xFF);
                scratch[j + 1] = (byte) ((hash >>> 8) & 0xFF);
            }
        }
        byte[] target = new byte[16];
        for (int i = 0; i < 16; i++) {
            byte lower = (byte) (scratch[i] & 0x7F);
            if ((lower >= 'A' && lower <= 'Z') || (lower >= 'a' && lower <= 'z'))
                target[i] = lower;
            else
                target[i] = (byte) (((scratch[i] >>> 4 & 0xF) + 0x61) & 0xFF);
        }
        return target;
    }

    private static int Hash(byte[] scratch, int hash) {
        for (int i = 15; i >= 0; i--)
            hash = ((hash >>> 8) & 0xFF ^ table[hash & 0xFF] ^ table[scratch[i] & 0xFF]) & 0xFFFF;
        return hash;
    }

}
Aldis
  • 439
  • 4
  • 10
1

There are several implementations of CRC-16. Progress Software (deliberately) does not document which variant is used.

For what purpose are you looking for this?

lavinio
  • 23,931
  • 5
  • 55
  • 71
  • 2
    We have a Progress Database in which are User and Passwords are stored, I'd like to use this Database as Authentication for another Application. – RaphaelH Aug 01 '12 at 07:46
1

Rather than trying to use "encode" I'd recommend studying OE's cryptography functionality. I'm not sure what 10.1C supports, the 11.0 docs I have says OE supports:

• DES — Data Encryption Standard
• DES3 — Triple DES
• AES — Advanced Encryption Standard
• RC4 — Also known as ARC4

The OE PDF docs are available here: http://communities.progress.com/pcom/docs/DOC-16074

Tim Kuehn
  • 3,201
  • 1
  • 17
  • 23
  • I know this is an old thread but I'd like to point out that the encode function is no good for use as authentication in that needs any real level of security. See http://labs.neohapsis.com/2008/08/25/crypto-pet-peeves-hashingencodingits-all-the-same-right/ for a good read about this. – Ian Stanway Jan 06 '15 at 13:01
0

The way how the ENCODE function only works one way. Progress has never disclosed the algorithm behind it. Plus they have never built in a function to decode.

As with OE 10.0B Progress has implemented cryptography within the ABL. Have a look at the ENCRYPT and DECRYPT function.

  • I do NOT want to decode anything. It's just for authentication purpose. So I want to do the same Encoding just in another Application – RaphaelH Aug 01 '12 at 12:25
  • If you are tied to the ENCODE function with the Progress database then I am afraid you won't have much luck because you won't find any official source for the algorithm Progress uses. – RealHeavyDude Aug 02 '12 at 14:20