i am using pgcrypto extension for password encryption in my PostgreSQL db. i am using same key to encrypt all passwords. When i use same key in different passwords(different strings) it gives same output.
Samples:
db=# select crypt('Sharon_1','alpha');
crypt
---------------
aljp4LCkDT1k.
(1 row)
Time: 2.025 ms
db=# select crypt('Sharon_1trgstysa','alpha');
crypt
---------------
aljp4LCkDT1k.
(1 row)
why is it like that?. When i pass two different strings it should give different encrypted strings as output.Is this a bug?. How can i solve this ? i can't change the key. The key should be always same.
Postgres version:
db=# select version();
PostgreSQL 11.4 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-28),
64-bit
Extension version:
db=# \dx pgcrypto
List of installed extensions
Name | Version | Schema | Description
----------+---------+--------+-------------------------
pgcrypto | 1.3 | public | cryptographic functions
pgcrypt is meant for something else:
Calculates a crypt(3)-style hash of password. When storing a new
password, you need to use gen_salt() to generate a new salt value. To
check a password, pass the stored hash value as salt, and test whether
the result matches the stored value.
The following CTE encrypts the passwords using a md5 salt algorithm and the select compares a given password with the ones in the CTE:
WITH j (val) AS (
VALUES
(crypt('Sharon_1',gen_salt('md5'))),
(crypt('Sharon_1trgstysa',gen_salt('md5')))
)
SELECT
val = crypt('Sharon_1',val), -- entered password to compare!
val -- stored password
FROM j;
?column? | val
----------+------------------------------------
t | $1$XpqL58HA$k2G55BjtVFQxHVe/jpu.2.
f | $1$0OIuDMkZ$PH2cDjG.aRzUAvtUtvf3E1
(2 Zeilen)
To encrypt and decrypt with symmetric PGP keys try pgp_sym_encrypt and pgp_sym_decrypt, e.g.
WITH j (val) AS (
VALUES
(pgp_sym_encrypt('Sharon_1','alpha')),
(pgp_sym_encrypt('Sharon_1trgstysa','alpha'))
)
SELECT pgp_sym_decrypt(val,'alpha') FROM j;
pgp_sym_decrypt
------------------
Sharon_1
Sharon_1trgstysa
(2 Zeilen)
The algorithm to be used by crypt is embedded in the format of the salt. Your salt "alpha" doesn't specify an algorithm, so crypt uses des. des only looks at the first 8 characters of the password (and the first 2 characters of the salt), and your two passwords don't differ in the first 8 characters.
i can't change the key.
Then your system is broken by design.
Related
The dump function in Oracle displays the internal representation of data:
DUMP returns a VARCHAR2 value containing the data type code, length in bytes, and internal representation of expr
Fore example:
SELECT DUMP(cast(1 as number ))
2 FROM DUAL;
DUMP(CAST(1ASNUMBER))
--------------------------------------------------------------------------------
Typ=2 Len=2: 193,2
SQL> SELECT DUMP(cast(1.000001 as number ))
2 FROM DUAL;
DUMP(CAST(1.000001ASNUMBER))
--------------------------------------------------------------------------------
Typ=2 Len=5: 193,2,1,1,2
It shows that the first 1 uses 2 byte for storing and the second example uses 5 bytes for storing.
I suppose the similar function in PostgreSQL is pg_typeof but it returns only the type name without information about byte usage:
SELECT pg_typeof(33);
pg_typeof
integer (1 row)
Does anybody know if there is an equivalent function in PostgreSQL?
I don't speak PostgreSQL.
However, Oracle functionality page says that there's Orafce which
implements in Postgres some of the functions from the Oracle database that are missing (or behaving differently)
It, furthermore, mentions the dump function
dump (anyexpr [, int]): Returns a text value that includes the datatype code, the length in bytes, and the internal representation of the expression
One of examples looks like this:
postgres=# select pg_catalog.dump('Pavel Stehule',10);
dump
-------------------------------------------------------------------------
Typ=25 Len=17: 68,0,0,0,80,97,118,101,108,32,83,116,101,104,117,108,101
(1 row)
To me, it looks like Oracle's dump:
SQL> select dump('Pavel Stehule') result from dual;
RESULT
--------------------------------------------------------------
Typ=96 Len=13: 80,97,118,101,108,32,83,116,101,104,117,108,101
SQL>
I presume you'll have to visit GitHub and install the package to see whether you can use it or not.
It is not a complete equivalent, but if you want to figure out the byte values used to encode a string in PostgreSQL, you can simply cast the value to bytea, which will give you the bytes in hexadecimal:
SELECT CAST ('schön' AS bytea);
This will work for strings, but not for numbers.
Oracle 12c:
SQL> select UTL_RAW.CAST_TO_RAW('Tom') as hex_val,
2 dbms_crypto.hash(src=>UTL_RAW.CAST_TO_RAW('Tom'), typ=>2) as hex_hash
3 from dual;
546F6D
D9FFACA46D5990EC39501BCDF22EE7A1
Postgresql 12.5:
sides=> select upper(encode('Tom', 'hex')), md5(upper(encode('Tom', 'hex')));
upper | md5
--------+----------------------------------
546F6D | f679fe36c1c908fa2547e6915026b0af
(1 row)
md5sum with newline:
-bash-4.2$ echo "546F6D" | md5sum
ef81d9f3f3e1305c92ce84efdecfd1bc -
md5sum without newline:
-bash-4.2$ echo -n "546F6D" | md5sum
f679fe36c1c908fa2547e6915026b0af -
As you can see, Postgres' MD5() function matches that of md5sum(1) without the newline. That's what I expected. However, the Oracle 12c doesn't match either, and nor does it match the md5 sum with newline?
What weirdness is Oracle doing (or am I making a PEBKAC mistake)?
(The ultimate purpose is to show the client that xml data successfully migrated from Oracle to Postgres. That's why weak hashing is acceptable.)
EDIT:
Using RAWTOHEX() returns the same value as CAST_TO_RAW().
SQL> select UTL_RAW.CAST_TO_RAW('Tom') as hex_val
2 , dbms_crypto.hash(src=>UTL_RAW.CAST_TO_RAW('Tom'), typ=>2) as hex_hash
3 , dbms_crypto.hash(src=>RAWTOHEX('Tom'), typ=>2) as raw_hash
4 from dual;
HEX_VAL
--------------------------------------------------------------------------------
HEX_HASH
--------------------------------------------------------------------------------
RAW_HASH
--------------------------------------------------------------------------------
546F6D
D9FFACA46D5990EC39501BCDF22EE7A1
D9FFACA46D5990EC39501BCDF22EE7A1
SQL> select UTL_RAW.CAST_TO_RAW('Tom') as hex_val
2 , dbms_crypto.hash(src=>UTL_RAW.CAST_TO_RAW('Tom'), typ=>2) as hex_hash
3 , dbms_crypto.hash(src=>RAWTOHEX('Tom'), typ=>2) as raw_hash
4 , standard_hash(rawtohex('Tom'), 'MD5') as std_hash
5 from dual;
HEX_VAL
--------------------------------------------------------------------------------
HEX_HASH
--------------------------------------------------------------------------------
RAW_HASH
--------------------------------------------------------------------------------
STD_HASH
--------------------------------
546F6D
D9FFACA46D5990EC39501BCDF22EE7A1
D9FFACA46D5990EC39501BCDF22EE7A1
F679FE36C1C908FA2547E6915026B0AF
Your Oracle command is hashing the hexidecimal value, but your Postgres and bash commands are hashing the hexadecimal representation. To have Oracle hash the string of the hexadecimal value, use RAWTOHEX:
SQL> select standard_hash(rawtohex('Tom'), 'MD5') from dual;
STANDARD_HASH(RAWTOHEX('TOM'),'M
--------------------------------
F679FE36C1C908FA2547E6915026B0AF
DBMS_CRYPTO and STANDARD_HASH work the same way, except that DBMS_CRYPTO only accepts the RAW data type.To confuse things, there is sometimes implicit conversions, and SQL*Plus may display different data types in different ways. But according to the UTL_RAW.CAST_TO_RAW documentation, "The data itself is not modified in any way, but its datatype is recast to a RAW datatype".
To compare raw values on both databases, compare select select dbms_crypto.hash(src=>utl_raw.cast_to_raw('Tom'), typ=>2) from dual; on Oracle with select upper(md5('Tom')); on Postgres - they both return D9FFACA46D5990EC39501BCDF22EE7A1.
I'm using: PostgreSQL 11.6 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.9.3, 64-bit running on AWS as Aurora (RDS).
I have managed to get the below working
SELECT encode(digest('email#example.com', 'sha256'),'hex');
But I need to use a salt provided by a 3rd party. Let's say for arguments sake the salt is 'this_is_my_salt'. How can I use this? i could only find examples that generate the salt using algorithms.
The vendor wants us to use their hash to compare email addresses in their database with ours. They haven't specified their Database system, but showed me their query which is:
SELECT 'email#example.com' as unhashed_email, sha2('shared_salt_value' || lower('email#example.com')) as hashed_email
And this produces a different hash to me trying the example in postgres using one of the answers below:
SELECT encode(digest('email#example.com' || 'shared_salt_value', 'sha256'),'hex');
My hash starts with db17e....
Their hash starts with b6c84....
Could it be encoding or something causing the difference?
That is trivial, just concatenate the string with the salt:
SELECT encode(digest('this_is_my_salt' || 'email#example.com', 'sha256'),'hex');
I have a column in a Postgres database that is of type varchar but has a binary value stored in it.
How can I return the binary value of the column in a way I can read it?
For example, at the moment I see "r" in the column, I want to see the 1's and 0's that make up the value for r.
To be a bit more clear about what I want.
I think the application is storing data about ticked checkboxes in binary.
So for a group of checkboxes:
Unchecked (0)
Checked (1)
Checked (1)
Checked (1)
Unchecked (0)
Unchecked (0)
Checked (1)
Unchecked (0)
it stores the value "r" and I want to see the binary or hex of the value that is stored. So for the value "r" I want to get the hex value "72" or the binary value "0111 0010"
Storing binary data in a text column is not a good idea. You can use the type bytea, e.g.:
drop table if exists my_table;
create table my_table(id serial primary key, switch bytea);
insert into my_table (switch) values
('\x7272'),
('\x1111'),
('\xffff');
You can easily set and get values in hex format, convert them to bit strings, get/set individual bytes/bits, e.g.:
select id,
switch,
right(switch::text, -1)::bit(16) as bits,
right(switch::text, -1)::bit(16)::int as int,
get_byte(switch, 0)
from my_table;
id | switch | bits | int | get_byte
----+--------+------------------+-------+----------
1 | \x7272 | 0111001001110010 | 29298 | 114
2 | \x1111 | 0001000100010001 | 4369 | 17
3 | \xffff | 1111111111111111 | 65535 | 255
(3 rows)
You can cast a text (varchar) to bytea:
select 'r'::bytea;
bytea
-------
\x72
(1 row)
Note that in some tools (e.g. PgAdmin III) you should set the parameter to get hex output:
set bytea_output to hex;
Per the documentation:
The output format depends on the configuration parameter bytea_output; the default is hex. (Note that the hex format was introduced in PostgreSQL 9.0; earlier versions and some tools don't understand it.)
Read also in the documentation:
Binary Data Types
Binary String Functions and Operators
Bit String Types
Bit String Functions and Operators
Using varchar for this is a bad idea. For example, you cannot store zero bytes that way.
Anyway, the answer to your question should be a simple type cast:
CAST(textcol AS bytea)
I'm looking for a DB2 function to calculate hashes on large CLOB values in order to quickly track changes. Other engines have functions such as CHECKSUM,CRC32 or MD5. The function in LUW is GET_HASH_VALUE but is not available in zOS.
Constraints: No access to UDFs or Stored Procedures.
Here is a quick and dirty code fragment that computes a CRC32, it only works to about 100 characters.
WITH crc(t,c,j) AS (
SELECT 'Hello World!',4294967295,0 FROM SYSIBM.SYSDUMMY1
UNION ALL
SELECT SUBSTR(t,2),bitxor(c,ASCII(t)),8 FROM crc WHERE t>'' AND j=0
UNION ALL
SELECT t,BITXOR(c/2,BITAND(3988292384,-BITAND(c,1))),j-1 FROM crc WHERE j>0
)
SELECT RIGHT(HEX(BITNOT(c)),8) FROM CRC WHERE t='' AND j=0
Result checked against http://www.lammertbies.nl/comm/info/crc-calculation.html :
1
--------
1C291CA3
Source: http://www.hackersdelight.org/hdcodetxt/crc.c.txt
The answer depends on which version of DB2 you have. If you are on DB2 9.7 or higher, have a look here: https://www.ibm.com/support/knowledgecenter/SSEPGG_9.7.0/com.ibm.db2.luw.sql.rtn.doc/doc/r0055167.html