public class SecurityOps
extends java.lang.Object
Progress Function Java Equivalent --------------------------- --------------------------- USERIDgetUserId()
USERID(dbname)getUserIdFromDB(com.goldencode.p2j.util.character)
ENCODEencode(com.goldencode.p2j.util.character)
BASE64-ENCODEbase64Encode(com.goldencode.p2j.util.BinaryData)
BASE64-DECODEbase64Decode(com.goldencode.p2j.util.Text)
ENCRYPTencrypt(java.lang.String)
GENERATE-PBE-KEYgeneratePBEKey(java.lang.String)
GENERATE-PBE-SALTgeneratePBESalt()
GENERATE-UUIDgenerateUUID()
SHA1-DIGESTsha1Digest(java.lang.String)
MDG-DIGESTmd5Digest(java.lang.String)
Modifier and Type | Field and Description |
---|---|
private static java.lang.String |
ALPHAS
Table of all alphabetic characters used to limit the encode output.
|
static int |
BLANK_ALLOWED
Database has userids stored in _user table, but do not enforce them.
|
static java.lang.String |
BLANK_USER |
private static boolean |
compatible
Flag to enable the old incompatible ENCODE.
|
private static int |
CORE_LOOP_PASSES
Number of iterations in the core encoding loop.
|
private static CustomSecurityOps |
customSecurityOps
The current _User security handler for emulation of USERID and SETUSERID P4GL functions
|
private static java.lang.String |
DEFAULT_SECURITY_OPS_HANDLER
The default classname for _User security handler
|
private static java.lang.String |
ERR12118
Progress error msg, can be shown while base64-encode method error
|
private static java.lang.String |
ERR12119
Progress error msg, can be shown while base64-decode method error
|
static int |
FREE_ACCESS
_User table of the database is empty, no access privilege needed
|
private static int |
INITIAL_CRC_VALUE
Initial CRC value.
|
private static java.util.logging.Logger |
LOG
Logger
|
private static int |
OUTPUT_ARRAY_SIZE
Number of bytes in the encoded output.
|
private static char |
PAD
Base64 PAD service symbol
|
private static int |
REVERSED_POLYNOMIAL
Reversed polynomial used with the CRC-16 algorithm.
|
static int |
STRICT
Only with valid user/password are allowed to access a database.
|
Constructor and Description |
---|
SecurityOps() |
Modifier and Type | Method and Description |
---|---|
static java.lang.String |
_encode(java.lang.String input)
Progress 4GL compatible
ENCODE algorithm which takes a source byte array
(of any size) and generates a 16-byte one-way hash using a proprietary approach
combined with a variant of CRC-16. |
private static java.lang.String |
_incompatible_encode(java.lang.String data)
Hashes an arbitrary input string into a 16-byte output string.
|
static memptr |
base64Decode(java.lang.String data)
Converts a base64 encoded string into a binary value and returns a
memptr with the decoded value.
|
static memptr |
base64Decode(Text data)
Decodes a base64 encoded string into a binary value.
|
static longchar |
base64Encode(BinaryData data)
Converts binary data into a Base64 encoded text.
|
static longchar |
base64Encode(byte[] data)
Converts binary data into a Base64 encoded text.
|
private static longchar |
base64Encode(memptr data)
Converts memptr into a Base64 encoded text.
|
static logical |
changePassword()
Performs a password change procedure for the currently logged on user.
|
private static boolean |
checkFormat(java.lang.String data)
Checks if the input string format conforms to Progress rules:
All trailing PAD symbols are ignored except the last one.
All characters must be from the base64 alphabet.
|
private static int |
crc16(short[] data,
int crc)
This implements a standard CRC-16 (also known as CRC-16-IBM or CRC-16-IBM) algorithm that
uses a reversed polynomial of 0xA001 and swapped byte ordering.
|
static character |
encode(character data)
ENCODE implementation which can be run in compatible mode (the default
which uses _encode(java.lang.String) as a worker) or in the incompatible mode using the J2SE
MD5 hashing algorithm. |
static character |
encode(java.lang.String data)
ENCODE implementation which can be run in compatible mode (the default
which uses _encode(java.lang.String) as a worker) or in the incompatible mode using the J2SE
MD5 hashing algorithm. |
static memptr |
encrypt(java.lang.String data)
Encrypts the source and returns a
memptr instance containing
the encrypted data. |
static memptr |
encrypt(java.lang.String data,
raw key)
Encrypts the source using the given key and returns a
memptr
instance containing the encrypted data. |
static memptr |
encrypt(java.lang.String data,
raw key,
raw ivValue)
Encrypts the source using the given key and initialization vector, and
returns a
memptr instance containing the encrypted data. |
static memptr |
encrypt(java.lang.String data,
raw key,
raw ivValue,
character algorithm)
Encrypts the source using the given key, initialization vector and
symmetric encryption algorithm, and returns a
memptr instance
containing the encrypted data. |
static memptr |
encrypt(java.lang.String data,
raw key,
raw ivValue,
java.lang.String algorithm)
Encrypts the source using the given key, initialization vector and
symmetric encryption algorithm, and returns a
memptr instance
containing the encrypted data. |
static memptr |
encrypt(Text data)
Encrypts the source and returns a
memptr instance containing
the encrypted data. |
static memptr |
encrypt(Text data,
raw key)
Encrypts the source using the given key and returns a
memptr
instance containing the encrypted data. |
static memptr |
encrypt(Text data,
raw key,
raw ivValue)
Encrypts the source using the given key and initialization vector, and
returns a
memptr instance containing the encrypted data. |
static memptr |
encrypt(Text data,
raw key,
raw ivValue,
character algorithm)
Encrypts the source using the given key, initialization vector and
symmetric encryption algorithm, and returns a
memptr instance
containing the encrypted data. |
static memptr |
encrypt(Text data,
raw key,
raw ivValue,
java.lang.String algorithm)
Encrypts the source using the given key, initialization vector and
symmetric encryption algorithm, and returns a
memptr instance
containing the encrypted data. |
static raw |
generatePBEKey(BinaryData password)
Generates a password-based encryption key, based on the PKCS#5/RFC 2898
standard, and returns the key as a
raw instance. |
static raw |
generatePBEKey(BinaryData password,
raw salt)
Generates a password-based encryption key, based on the PKCS#5/RFC 2898
standard, and returns the key as a
raw instance. |
static raw |
generatePBEKey(java.lang.String password)
Generates a password-based encryption key, based on the PKCS#5/RFC 2898
standard, and returns the key as a
raw instance. |
static raw |
generatePBEKey(java.lang.String password,
raw salt)
Generates a password-based encryption key, based on the PKCS#5/RFC 2898
standard, and returns the key as a
raw instance. |
static raw |
generatePBEKey(Text password)
Generates a password-based encryption key, based on the PKCS#5/RFC 2898
standard, and returns the key as a
raw instance. |
static raw |
generatePBEKey(Text password,
raw salt)
Generates a password-based encryption key, based on the PKCS#5/RFC 2898
standard, and returns the key as a
raw instance. |
static raw |
generatePBESalt()
Generates a random salt value (a series of 8 bytes) to use in generating
an encryption key, and returns the salt value as a
raw instance. |
static raw |
generateUUID()
Generate a 16-bit UUID.
|
static int |
getAuthLevel(java.lang.String ldbname)
Check the access level for a database.
|
private static CustomSecurityOps |
getDefaultUserHandler()
Instantiate the default _User handler and returns it.
|
static java.lang.String |
getDefaultUserid()
Returns the default userid used for authentication to databases that do not have _User
meta-table populated.
|
static java.lang.String |
getDefaultUserid(java.lang.String ldbname)
Returns the default userid used for authentication to databases.
|
static character |
getUserId()
Returns the userid associated with the current user.
|
static character |
getUserIdFromDB(character dbname)
Returns the userid associated with the current user of the given logical database.
|
static character |
getUserIdFromDB(java.lang.String dbname)
Returns the userid associated with the current user of the given logical database.
|
static boolean |
hasAccessToDatabase(java.lang.String ldbName)
Checks if the currently authenticated user has access to a database.
|
static raw |
hexDecode(java.lang.String data)
Converts a hexadecimal encoded string into a binary value and returns a
raw with the decoded value.
|
static raw |
hexDecode(Text data)
Converts a hexadecimal encoded string into a binary value and returns a
raw with the decoded value.
|
static character |
hexEncode(raw data)
Converts a binary value into a hexadecimal encoded string and returns a
the encoded value.
|
private static CustomSecurityOps |
instantiateUserHandler()
Instantiates and returns a SecurityOps handler for emulation of USERID and SETUSERID P4GL
functions as configured in the directory.
|
private static boolean |
isBase64(char c)
Checks if the symbol from base64 alphabet:
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
static raw |
md5Digest(BinaryData data)
Hashes the specified data using RSA MD5 algorithm, and returns a 16-byte
binary message digest value in a
raw instance. |
static raw |
md5Digest(BinaryData data,
BinaryData key)
Hashes the specified data using RSA MD5 algorithm, and returns a 16-byte
binary message digest value in a
raw instance. |
static raw |
md5Digest(BinaryData data,
java.lang.String key)
Hashes the specified data using RSA MD5 algorithm, and returns a 16-byte
binary message digest value in a
raw instance. |
static raw |
md5Digest(BinaryData data,
Text key)
Hashes the specified data using RSA MD5 algorithm, and returns a 16-byte
binary message digest value in a
raw instance. |
static raw |
md5Digest(java.lang.String data)
Hashes the specified data using RSA MD5 algorithm, and returns a 16-byte
binary message digest value in a
raw instance. |
static raw |
md5Digest(java.lang.String data,
BinaryData key)
Hashes the specified data using RSA MD5 algorithm, and returns a 16-byte
binary message digest value in a
raw instance. |
static raw |
md5Digest(java.lang.String data,
java.lang.String key)
Hashes the specified data using RSA MD5 algorithm, and returns a 16-byte
binary message digest value in a
raw instance. |
static raw |
md5Digest(java.lang.String data,
Text key)
Hashes the specified data using RSA MD5 algorithm, and returns a 16-byte
binary message digest value in a
raw instance. |
static raw |
md5Digest(Text data)
Hashes the specified data using RSA MD5 algorithm, and returns a 16-byte
binary message digest value in a
raw instance. |
static raw |
md5Digest(Text data,
BinaryData key)
Hashes the specified data using RSA MD5 algorithm, and returns a 16-byte
binary message digest value in a
raw instance. |
static raw |
md5Digest(Text data,
java.lang.String key)
Hashes the specified data using RSA MD5 algorithm, and returns a 16-byte
binary message digest value in a
raw instance. |
static raw |
md5Digest(Text data,
Text key)
Hashes the specified data using RSA MD5 algorithm, and returns a 16-byte
binary message digest value in a
raw instance. |
static logical |
setUserId(character userid,
character password)
Authenticates the user for specified DB connection.
|
static logical |
setUserId(character userid,
character password,
character dbname)
Authenticates the user for specified DB connection.
|
static logical |
setUserId(character userid,
character password,
java.lang.String dbname)
Authenticates the user for specified DB connection.
|
static logical |
setUserId(character userid,
java.lang.String password)
Authenticates the user for specified DB connection.
|
static logical |
setUserId(character userid,
java.lang.String password,
character dbname)
Authenticates the user for specified DB connection.
|
static logical |
setUserId(character userid,
java.lang.String password,
java.lang.String dbname)
Authenticates the user for specified DB connection.
|
static logical |
setUserId(java.lang.String userid,
character password)
Authenticates the user for specified DB connection.
|
static logical |
setUserId(java.lang.String userid,
character password,
character dbname)
Authenticates the user for specified DB connection.
|
static logical |
setUserId(java.lang.String userid,
character password,
java.lang.String dbname)
Authenticates the user for specified DB connection.
|
static logical |
setUserId(java.lang.String userid,
java.lang.String password)
Authenticates the user for specified DB connection.
|
static logical |
setUserId(java.lang.String userid,
java.lang.String password,
character dbname)
Authenticates the user for specified DB connection.
|
static logical |
setUserId(java.lang.String userid,
java.lang.String password,
java.lang.String dbname)
Authenticates the user for specified DB connection.
|
static raw |
sha1Digest(BinaryData data)
Hashes the specified data using the SHA-1 algorithm, and returns a
20-byte binary message digest value in a
raw instance. |
static raw |
sha1Digest(BinaryData data,
BinaryData key)
Hashes the specified data using the SHA-1 algorithm, and returns a
20-byte binary message digest value in a
raw instance. |
static raw |
sha1Digest(BinaryData data,
java.lang.String key)
Hashes the specified data using the SHA-1 algorithm, and returns a
20-byte binary message digest value in a
raw instance. |
static raw |
sha1Digest(BinaryData data,
Text key)
Hashes the specified data using the SHA-1 algorithm, and returns a
20-byte binary message digest value in a
raw instance. |
static raw |
sha1Digest(java.lang.String data)
Hashes the specified data using the SHA-1 algorithm, and returns a
20-byte binary message digest value in a
raw instance. |
static raw |
sha1Digest(java.lang.String data,
BinaryData key)
Hashes the specified data using the SHA-1 algorithm, and returns a
20-byte binary message digest value in a
raw instance. |
static raw |
sha1Digest(java.lang.String data,
java.lang.String key)
Hashes the specified data using the SHA-1 algorithm, and returns a
20-byte binary message digest value in a
raw instance. |
static raw |
sha1Digest(java.lang.String data,
Text key)
Hashes the specified data using the SHA-1 algorithm, and returns a
20-byte binary message digest value in a
raw instance. |
static raw |
sha1Digest(Text data)
Hashes the specified data using the SHA-1 algorithm, and returns a
20-byte binary message digest value in a
raw instance. |
static raw |
sha1Digest(Text data,
BinaryData key)
Hashes the specified data using the SHA-1 algorithm, and returns a
20-byte binary message digest value in a
raw instance. |
static raw |
sha1Digest(Text data,
java.lang.String key)
Hashes the specified data using the SHA-1 algorithm, and returns a
20-byte binary message digest value in a
raw instance. |
static raw |
sha1Digest(Text data,
Text key)
Hashes the specified data using the SHA-1 algorithm, and returns a
20-byte binary message digest value in a
raw instance. |
private static void |
sourceToTargetXor(int[] source,
short[] target)
Walk forward through the array of source data provided and XOR each byte into the target
array, but with the index of the target matching a backwards walk.
|
private static byte[] |
translateToAlpha(short[] source)
Convert the source array into an array of bytes with the same number of elements, but
where each byte may only contain uppercase or lowercase English alphabetic characters
(a-z and A-Z).
|
public static final java.lang.String BLANK_USER
public static final int FREE_ACCESS
public static final int BLANK_ALLOWED
public static final int STRICT
private static final java.lang.String DEFAULT_SECURITY_OPS_HANDLER
private static final java.util.logging.Logger LOG
private static final java.lang.String ALPHAS
private static final java.lang.String ERR12118
private static final java.lang.String ERR12119
private static final char PAD
private static final int INITIAL_CRC_VALUE
private static final int OUTPUT_ARRAY_SIZE
private static final int CORE_LOOP_PASSES
private static final int REVERSED_POLYNOMIAL
private static CustomSecurityOps customSecurityOps
private static boolean compatible
private static CustomSecurityOps instantiateUserHandler()
private static CustomSecurityOps getDefaultUserHandler()
public static character getUserId()
Note that in Progress 4GL, this takes an optional string parameter with the name of the logical database in which the userid is set. There is no corresponding database level authentication concept in P2J so this parameter is not supported.
public static character getUserIdFromDB(character dbname)
This will call the current configured implementation of CustomSecurityOps. If the database _User metadata is enabled then the authenticated user is returned, otherwise the default SecurityManager user is returned.
dbname
- Logical database name.public static character getUserIdFromDB(java.lang.String dbname)
This will call the current configured implementation of CustomSecurityOps. If the database _User metadata is enabled then the authenticated user is returned, otherwise the default SecurityManager user is returned.
dbname
- Logical database name.public static java.lang.String getDefaultUserid(java.lang.String ldbname)
getDefaultUserid()
user id.ldbname
- The logical name of the database.public static java.lang.String getDefaultUserid()
public static logical setUserId(java.lang.String userid, character password, character dbname)
userid
- The name of the user to set as UserID.password
- The users password.dbname
- Logical database name.true
in case of valid user match false
otherwise.public static logical setUserId(character userid, java.lang.String password, character dbname)
userid
- The name of the user to set as UserID.password
- The users password.dbname
- Logical database name.true
in case of valid user match false
otherwise.public static logical setUserId(java.lang.String userid, java.lang.String password, character dbname)
userid
- The name of the user to set as UserID.password
- The users password.dbname
- Logical database name.true
in case of valid user match false
otherwise.public static logical setUserId(character userid, character password, java.lang.String dbname)
userid
- The name of the user to set as UserID.password
- The users password.dbname
- Logical database name.true
in case of valid user match false
otherwise.public static logical setUserId(java.lang.String userid, character password, java.lang.String dbname)
userid
- The name of the user to set as UserID.password
- The users password.dbname
- Logical database name.true
in case of valid user match false
otherwise.public static logical setUserId(character userid, java.lang.String password, java.lang.String dbname)
userid
- The name of the user to set as UserID.password
- The users password.dbname
- Logical database name.true
in case of valid user match false
otherwise.public static logical setUserId(java.lang.String userid, java.lang.String password, java.lang.String dbname)
userid
- The name of the user to set as UserID.password
- The users password.dbname
- Logical database name.true
in case of valid user match false
otherwise.public static logical setUserId(java.lang.String userid, character password)
userid
- The name of the user to set as UserID.password
- The users password.true
in case of valid user match false
otherwise.public static logical setUserId(character userid, java.lang.String password)
userid
- The name of the user to set as UserID.password
- The users password.true
in case of valid user match false
otherwise.public static logical setUserId(java.lang.String userid, java.lang.String password)
userid
- The name of the user to set as UserID.password
- The users password.true
in case of valid user match false
otherwise.public static logical setUserId(character userid, character password)
userid
- The name of the user to set as UserID.password
- The users password.true
in case of valid user match false
otherwise.public static logical setUserId(character userid, character password, character dbname)
userid
- The name of the user to set as UserID.password
- The users password.dbname
- Logical database name.true
in case of valid user match false
otherwise.public static boolean hasAccessToDatabase(java.lang.String ldbName)
SecurityOps
is
configured with the default SecurityManagerSecurityOps
.
MetadataSecurityOps
, if the database does not have any users
defined in _user meta table the authentication is not enforced so any user can access
it. Otherwise, the user must have entered a correct combination of userid / password
to get access to respective database.
ldbName
- The logical name of the database.true
if access to requested database is permitted for currently
authenticated user.public static int getAuthLevel(java.lang.String ldbname)
ldbname
- The logical database name to query.public static logical changePassword()
Application has no control over the procedure itself.
true
meanspublic static character encode(character data)
ENCODE
implementation which can be run in compatible mode (the default
which uses _encode(java.lang.String)
as a worker) or in the incompatible mode using the J2SE
MD5 hashing algorithm. The choice of which version to run is made using a flag
that is initialized from the directory when the server starts.
WARNING: when the incompatible version is used the implementation is NOT compatible with the Progress 4GL algorithm in any way. Any programs relying on comparisons between data encoded by the Progress 4GL ENCODE and the return value from this method will NOT compare as expected.
By default, the Progress 4GL compatible ENCODE
algorithm is truly compatible
and it will operate on stored/migrated values from the original system as expected. The
algorithm takes a source byte array (of any size) and generates a 16-byte one-way hash
using a 4GL-proprietary approach combined with a variant of CRC-16. The basic approach is
to spread out the source data in an intermediate accumulator array of 16 unsigned bytes
and to repeatedly CRC that data and copy the resulting 2-byte CRC into successive elements
of this intermediate accumulator, while building the next CRC results on the accumulated
CRC value and the recently modified intermediate accumulator. This set of CRCs is
calculated 8 times (since that will generate 16 bytes). This basic approach is executed 5
times in a row. Each byte of the resulting hashed intermediate accumulator array is then
translated into one of the 52 possible uppercase or lowercase English alphabetic
characters. That translated result is returned.
The detailed COMPATIBLE algorithm:
sourceToTargetXor(int[], short[])
method for details
as well as the significant cryptographic limitations this causes.
crc16(short[], int)
method, passing in both the intermediate output
accumulator as well as the CRC accumulator. This is the core CRC
algorithm and it will calculate the CRC of the current state of the
intermediate output accumulator while including the initial state of
the CRC accumulator. The resulting returned CRC result is assigned
back to the CRC accumulator. The CRC-16 algorithm used is not
cryptographically sound. It generates a non-uniform distribution of
hashed data and collisions are not rare.
translateToAlpha(short[])
method for details on this process
and for the severe limitations of the resulting non-uniform distribution.
The result of this algorithm is NOT cryptographically sound. It should not be used for
secure purposes. The flaws in this algorithm come from the processing associated with
sourceToTargetXor(int[], short[])
, crc16(short[], int)
and translateToAlpha(short[])
.
data
- The data to be encoded. This must not be null
. The string may be
of any length. The data will be truncated at any contained null characters.unknown value
if the input is
null
or unknown value
.public static character encode(java.lang.String data)
ENCODE
implementation which can be run in compatible mode (the default
which uses _encode(java.lang.String)
as a worker) or in the incompatible mode using the J2SE
MD5 hashing algorithm. The choice of which version to run is made using a flag
that is initialized from the directory when the server starts.
WARNING: when the incompatible version is used the implementation is NOT compatible with the Progress 4GL algorithm in any way. Any programs relying on comparisons between data encoded by the Progress 4GL ENCODE and the return value from this method will NOT compare as expected.
By default, the Progress 4GL compatible ENCODE
algorithm is truly compatible
and it will operate on stored/migrated values from the original system as expected. The
algorithm takes a source byte array (of any size) and generates a 16-byte one-way hash
using a 4GL-proprietary approach combined with a variant of CRC-16. The basic approach is
to spread out the source data in an intermediate accumulator array of 16 unsigned bytes
and to repeatedly CRC that data and copy the resulting 2-byte CRC into successive elements
of this intermediate accumulator, while building the next CRC results on the accumulated
CRC value and the recently modified intermediate accumulator. This set of CRCs is
calculated 8 times (since that will generate 16 bytes). This basic approach is executed 5
times in a row. Each byte of the resulting hashed intermediate accumulator array is then
translated into one of the 52 possible uppercase or lowercase English alphabetic
characters. That translated result is returned.
The detailed COMPATIBLE algorithm:
sourceToTargetXor(int[], short[])
method for details
as well as the significant cryptographic limitations this causes.
crc16(short[], int)
method, passing in both the intermediate output
accumulator as well as the CRC accumulator. This is the core CRC
algorithm and it will calculate the CRC of the current state of the
intermediate output accumulator while including the initial state of
the CRC accumulator. The resulting returned CRC result is assigned
back to the CRC accumulator. The CRC-16 algorithm used is not
cryptographically sound. It generates a non-uniform distribution of
hashed data and collisions are not rare.
translateToAlpha(short[])
method for details on this process
and for the severe limitations of the resulting non-uniform distribution.
The result of this algorithm is NOT cryptographically sound. It should not be used for
secure purposes. The flaws in this algorithm come from the processing associated with
sourceToTargetXor(int[], short[])
, crc16(short[], int)
and translateToAlpha(short[])
.
data
- The data to be encoded. This must not be null
. The string may be
of any length. The data will be truncated at any contained null characters.unknown value
if the input is
null
.public static java.lang.String _encode(java.lang.String input)
ENCODE
algorithm which takes a source byte array
(of any size) and generates a 16-byte one-way hash using a proprietary approach
combined with a variant of CRC-16. The basic approach is to spread out the source data
in an intermediate accumulator array of 16 unsigned bytes and to repeatedly CRC that data
and copy the resulting 2-byte CRC into successive elements of this intermediate
accumulator, while building the next CRC results on the accumulated CRC value and the
recently modified intermediate accumulator. This set of CRCs is calculated 8 times
(since that will generate 16 bytes). This basic approach is executed 5 times in a row.
Each byte of the resulting hashed intermediate accumulator array is then translated into
one of the 52 possible uppercase or lowercase English alphabetic characters. That
translated result is returned.
The detailed algorithm:
sourceToTargetXor(int[], short[])
method for details
as well as the significant cryptographic limitations this causes.
crc16(short[], int)
method, passing in both the intermediate output
accumulator as well as the CRC accumulator. This is the core CRC
algorithm and it will calculate the CRC of the current state of the
intermediate output accumulator while including the initial state of
the CRC accumulator. The resulting returned CRC result is assigned
back to the CRC accumulator. The CRC-16 algorithm used is not
cryptographically sound. It generates a non-uniform distribution of
hashed data and collisions are not rare.
translateToAlpha(short[])
method for details on this process
and for the severe limitations of the resulting non-uniform distribution.
The result of this algorithm is NOT cryptographically sound. It should not be used for
secure purposes. The flaws in this algorithm come from the processing associated with
sourceToTargetXor(int[], short[])
, crc16(short[], int)
and translateToAlpha(short[])
.
input
- The data to be encoded. This must not be null
. The string may be
of any length. The data will be truncated at any contained null characters.public static longchar base64Encode(BinaryData data)
data
- The data to be encoded.unknown
will be returned if the given data is
unknown
OR if the given data is initialized but the runtime has no
knowledge of the buffer's size.public static longchar base64Encode(byte[] data)
data
- The data to be encoded.unknown
will be returned if the given data is
null
.public static memptr base64Decode(Text data)
data
- The string to be decoded.public static memptr base64Decode(java.lang.String data)
data
- The string to be decoded.public static raw hexDecode(Text data)
data
- The text to be decoded. null
will be treated like
unknown value.public static raw hexDecode(java.lang.String data)
data
- The string to be decoded. null
will be treated like
unknown value.public static character hexEncode(raw data)
data
- The text to be encoded. null
will be treated like
unknown value.public static memptr encrypt(java.lang.String data)
memptr
instance containing
the encrypted data.data
- The data to be encrypted.public static memptr encrypt(java.lang.String data, raw key)
memptr
instance containing the encrypted data.data
- The data to be encrypted.key
- The encryption key.public static memptr encrypt(java.lang.String data, raw key, raw ivValue)
memptr
instance containing the encrypted data.data
- The data to be encrypted.key
- The encryption key.ivValue
- An initialization vector to be used with the given key.public static memptr encrypt(java.lang.String data, raw key, raw ivValue, java.lang.String algorithm)
memptr
instance
containing the encrypted data.data
- The data to be encrypted.key
- The encryption key.ivValue
- An initialization vector to be used with the given key.algorithm
- The encryption algorithm's name.public static memptr encrypt(java.lang.String data, raw key, raw ivValue, character algorithm)
memptr
instance
containing the encrypted data.data
- The data to be encrypted.key
- The encryption key.ivValue
- An initialization vector to be used with the given key.algorithm
- The encryption algorithm's name.public static memptr encrypt(Text data)
memptr
instance containing
the encrypted data.data
- The data to be encrypted.public static memptr encrypt(Text data, raw key)
memptr
instance containing the encrypted data.data
- The data to be encrypted.key
- The encryption key.public static memptr encrypt(Text data, raw key, raw ivValue)
memptr
instance containing the encrypted data.data
- The data to be encrypted.key
- The encryption key.ivValue
- An initialization vector to be used with the given key.public static memptr encrypt(Text data, raw key, raw ivValue, java.lang.String algorithm)
memptr
instance
containing the encrypted data.data
- The data to be encrypted.key
- The encryption key.ivValue
- An initialization vector to be used with the given key.algorithm
- The encryption algorithm's name.public static memptr encrypt(Text data, raw key, raw ivValue, character algorithm)
memptr
instance
containing the encrypted data.data
- The data to be encrypted.key
- The encryption key.ivValue
- An initialization vector to be used with the given key.algorithm
- The encryption algorithm's name.public static raw generatePBEKey(java.lang.String password)
raw
instance.password
- The password to use in generating the encryption key.public static raw generatePBEKey(java.lang.String password, raw salt)
raw
instance.password
- The password to use in generating the encryption key.salt
- a random series of 8 bytes to use as salt value in generating
the encryption key.public static raw generatePBEKey(Text password)
raw
instance.password
- The password to use in generating the encryption key.public static raw generatePBEKey(Text password, raw salt)
raw
instance.password
- The password to use in generating the encryption key.salt
- a random series of 8 bytes to use as salt value in generating
the encryption key.public static raw generatePBEKey(BinaryData password)
raw
instance.password
- The password to use in generating the encryption key.public static raw generatePBEKey(BinaryData password, raw salt)
raw
instance.password
- The password to use in generating the encryption key.salt
- a random series of 8 bytes to use as salt value in generating
the encryption key.public static raw generatePBESalt()
raw
instance.public static raw generateUUID()
public static raw sha1Digest(java.lang.String data)
raw
instance.data
- The data to be hashed.public static raw sha1Digest(java.lang.String data, java.lang.String key)
raw
instance.data
- The data to be hashed.key
- An optional key value to use in the hash operation.public static raw sha1Digest(java.lang.String data, Text key)
raw
instance.data
- The data to be hashed.key
- An optional key value to use in the hash operation.public static raw sha1Digest(java.lang.String data, BinaryData key)
raw
instance.data
- The data to be hashed.key
- An optional key value to use in the hash operation.public static raw sha1Digest(Text data)
raw
instance.data
- The data to be hashed.public static raw sha1Digest(Text data, java.lang.String key)
raw
instance.data
- The data to be hashed.key
- An optional key value to use in the hash operation.public static raw sha1Digest(Text data, Text key)
raw
instance.data
- The data to be hashed.key
- An optional key value to use in the hash operation.public static raw sha1Digest(Text data, BinaryData key)
raw
instance.data
- The data to be hashed.key
- An optional key value to use in the hash operation.public static raw sha1Digest(BinaryData data)
raw
instance.data
- The data to be hashed.public static raw sha1Digest(BinaryData data, java.lang.String key)
raw
instance.data
- The data to be hashed.key
- An optional key value to use in the hash operation.public static raw sha1Digest(BinaryData data, Text key)
raw
instance.data
- The data to be hashed.key
- An optional key value to use in the hash operation.public static raw sha1Digest(BinaryData data, BinaryData key)
raw
instance.data
- The data to be hashed.key
- An optional key value to use in the hash operation.public static raw md5Digest(java.lang.String data)
raw
instance.data
- The data to be hashed.public static raw md5Digest(java.lang.String data, java.lang.String key)
raw
instance.data
- The data to be hashed.key
- An optional key value to use in the hash operation.public static raw md5Digest(java.lang.String data, Text key)
raw
instance.data
- The data to be hashed.key
- An optional key value to use in the hash operation.public static raw md5Digest(java.lang.String data, BinaryData key)
raw
instance.data
- The data to be hashed.key
- An optional key value to use in the hash operation.public static raw md5Digest(Text data)
raw
instance.data
- The data to be hashed.public static raw md5Digest(Text data, java.lang.String key)
raw
instance.data
- The data to be hashed.key
- An optional key value to use in the hash operation.public static raw md5Digest(Text data, Text key)
raw
instance.data
- The data to be hashed.key
- An optional key value to use in the hash operation.public static raw md5Digest(Text data, BinaryData key)
raw
instance.data
- The data to be hashed.key
- An optional key value to use in the hash operation.public static raw md5Digest(BinaryData data)
raw
instance.data
- The data to be hashed.public static raw md5Digest(BinaryData data, java.lang.String key)
raw
instance.data
- The data to be hashed.key
- An optional key value to use in the hash operation.public static raw md5Digest(BinaryData data, Text key)
raw
instance.data
- The data to be hashed.key
- An optional key value to use in the hash operation.public static raw md5Digest(BinaryData data, BinaryData key)
raw
instance.data
- The data to be hashed.key
- An optional key value to use in the hash operation.private static longchar base64Encode(memptr data)
There were reports that the error 12118 was raised (Unable to allocate memory for result from function) but at this moment a recreate is unavailable. It is possible there is a scenario in which memory is somehow constrained on the runtime system and this error would be generated. Since there is no known recreate at this time, the corresponding error processing is not implemented.
data
- The data to be encoded.unknown
will be returned if the given data is
null
or unknown
private static boolean checkFormat(java.lang.String data)
isBase64(char)
.
data
- The string to be decoded by Base64private static boolean isBase64(char c)
c
- input character to checkprivate static java.lang.String _incompatible_encode(java.lang.String data)
WARNING: this implementation is NOT compatible with the Progress 4GL algorithm in any way. Any programs relying on comparisons between data encoded by the Progress 4GL ENCODE and the return value from this method will NOT compare as expected.
The 16-bytes of output will only include characters in the range A-Z
and
a-z
.
This is only here because there is at least 1 customer that has installations that have stored values that were encoded with the incompatible version. Remove this at such time as it is no longer in use.
data
- The data to be hashed. Must not be null
.private static void sourceToTargetXor(int[] source, short[] target)
From a cryptographic perspective, the algorithm is quite poor. Source arrays smaller than the target arrays will leave target array bytes unmodified. Source arrays larger than the target array size will have some (or all) elements modified multiple times. Both cases are causes of concern. Not modifying elements means that there is less input provided for distribution of results. Modifying elements more than once can cause issues as well. Consider the case where the same character appears in the source array in the first byte (index 0) and in the byte modulo the size of the target. Because of wrapping, this character will be XOR'd twice into the same element of the target array. XOR is its own inverse. If you XOR the same data into a byte an even number of times, then the resulting byte will be unchanged. This will have the effect of reducing the distribution of the resulting data for some inputs. This is not suitable for secure purposes.
source
- Source array to XOR from. Must not be null
. May be of any length.target
- Target array to XOR into. Must not be null
. May be of any length.private static int crc16(short[] data, int crc)
If this algorithm generated uniformly distributed hashes, then in a best case scenario the probability of a collision between any 2 items is (1 / 2^16) or .00152588 %. That seems good until one considers that between any 300 items there is a 50% chance of collisions and between any 430 items there is a 75% chance of a collision! This is the well known birthday problem (see http://en.wikipedia.org/wiki/Birthday_attack).
Please note that the CRC-16 algorithm is not suitable for cryptographic hashing. It does NOT generate uniformly distributed hashes. This means that the collision rate is not even as good as the best case scenario. Even if it did have uniform distribution, the small number of bits means that collisions are not very rare. CRC is more suitable for error detection. It should NOT be used for secure purposes.
data
- The bytes of data to CRC.crc
- The initial CRC value into which each element of the data will be XOR'd.private static byte[] translateToAlpha(short[] source)
The source array will have each element translated into a corresponding element in the output array. Only the least significant byte of the source array element is considered in the translation algorithm. The order of the elements in the output array will be the same order as the source array (e.g. the first source element translates to the first output element and so forth).
The following algorithm is used to translate the 256 possible source byte values into the 52 possible output byte values:
Assuming the source bytes are uniformly distributed, this translation approach is guaranteed to result in a highly UNEVEN distribution of output bytes. This is cryptographically BAD and should NOT be used for secure purposes. To understand why this occurs:
Source Byte Range Output Byte Distribution Notes ----------------- ----------- ---------------------------------------------------------------------------- 0x00 - 0x40 'a' - 'e' 'a' through 'd' are 16X more likely than 'e' 0x41 - 0x5A 'A' - 'Z' all equally likely (1 to 1 mapping of input and output) 0x5B - 0x60 'f' - 'g' 'f' 5X more likely than 'g' 0x61 - 0x7A 'a' - 'z' all equally likely (1 to 1 mapping of input and output) 0x7B - 0xC0 'h' - 'm' 'i' through 'l' are 16X more likely than 'm', 'h' is 5X more likely than 'm' 0xC1 - 0xDA 'A' - 'Z' all equally likely (1 to 1 mapping of input and output) 0xDB - 0xE0 'n' - 'o' 'n' 5X more likely than 'o' 0xE1 - 0xFA 'a' - 'z' all equally likely (1 to 1 mapping of input and output) 0xFB - 0xFF 'p' only 'p' is possible
More graphically, here is the exact distribution that will occur for perfectly distributed input:
Character Frequency Histogram --------- --------- ----------------------- A 2 ++ B 2 ++ C 2 ++ D 2 ++ E 2 ++ F 2 ++ G 2 ++ H 2 ++ I 2 ++ J 2 ++ K 2 ++ L 2 ++ M 2 ++ N 2 ++ O 2 ++ P 2 ++ Q 2 ++ R 2 ++ S 2 ++ T 2 ++ U 2 ++ V 2 ++ W 2 ++ X 2 ++ Y 2 ++ Z 2 ++ a 18 ++++++++++++++++++ b 18 ++++++++++++++++++ c 18 ++++++++++++++++++ d 18 ++++++++++++++++++ e 3 +++ f 7 +++++++ g 3 +++ h 7 +++++++ i 18 ++++++++++++++++++ j 18 ++++++++++++++++++ k 18 ++++++++++++++++++ l 18 ++++++++++++++++++ m 3 +++ n 7 +++++++ o 3 +++ p 7 +++++++ q 2 ++ r 2 ++ s 2 ++ t 2 ++ u 2 ++ v 2 ++ w 2 ++ x 2 ++ y 2 ++ z 2 ++
This non-uniform distribution is purely due to the fallback approach of using the upper nibble of some bytes as a selector into a subset of the possible output values. Since the only a subset of the output values are targeted, it makes those values more likely to occur. In addition, because there are some upper nibble values that are less likely to be encountered (because they rarely trigger the fallback mechanism in the first place), this causes an additional level of non-uniformity even within the subset that is possible to be selected.
source
- The bytes to convert. Must not be null
. Only the least
significant byte of each element will be used.