34 | | As you can see from this table, both OpenVista and WorldVistA have done badly (it's not known whether the OpenVista version is even legal) while vxVista has done the best. |
| 34 | As you can see from this table, both OpenVista and WorldVistA have done badly (it's not known whether the OpenVista version is even legal) while vxVista has done the best. |
| 35 | |
| 36 | == A solution to hashing and encryption on GT.M == |
| 37 | I wrote this routine to replace XUSHSHP: |
| 38 | {{{ |
| 39 | UJOSHSHP ; VEN/SMH - Encrypt Data a la XUSHSHP ;2013-02-27 9:44 AM |
| 40 | ;;1.0;JORDAN SPECIFIC MODIFICATIONS; |
| 41 | ; |
| 42 | HASH ; HASH |
| 43 | Q:'$D(X) Q:'$L(X) |
| 44 | ; Input: X from Symbol Table. X can be any length |
| 45 | ; Output: X hashed, as 20 characters |
| 46 | ; |
| 47 | ; Use sha512 with user stuff as salt |
| 48 | ; Should use PBKDF2, bcrypt, or scrypt; but not available in openssl CLI. |
| 49 | S X=$$UP^XLFSTR(X) ; Uppercase X; per original VA code. |
| 50 | N SALTED S SALTED=$P(^VA(200,DUZ,1),U,7)_X_DUZ ; Salt X with User Creation Date and DUZ. |
| 51 | N CALL S CALL="openssl dgst -sha512" ; SHA512 OS call |
| 52 | N DEVICE S DEVICE="hashPipe" |
| 53 | N OUTPUT |
| 54 | N OLDIO S OLDIO=$IO |
| 55 | OPEN DEVICE:(shell="/bin/sh":comm=CALL)::"PIPE" |
| 56 | USE DEVICE WRITE SALTED,/EOF READ OUTPUT:1 U OLDIO CLOSE DEVICE |
| 57 | S X=$E(OUTPUT,$L(OUTPUT)-19,$L(OUTPUT)) ; X is the return variable; only 20 characters long |
| 58 | QUIT |
| 59 | ; |
| 60 | EN ; ENCRYPT |
| 61 | Q:'$D(X)!('$D(X1))!('$D(X2)) Q:'$L(X) |
| 62 | ; Expect X, X1, X2 |
| 63 | ; X is the string to encrypt. X1 and X2 are salts/password |
| 64 | ; X1 can be the DUZ |
| 65 | ; X2 can be the checksum of the text to encrypt |
| 66 | ; Output: X, the encrypted string. Length is the same the input. |
| 67 | ; Maximum supported length is maximum global node length. |
| 68 | ; Encrypting word processing fields is not supported. |
| 69 | ; |
| 70 | ; AES- Cipher Block Chaining with Base 64 encoding with password w no salt. |
| 71 | N CALL S CALL="openssl enc -a -aes-256-cbc -nosalt -pass pass:"_X1_X2 |
| 72 | ; N CALL S CALL="openssl enc -a -des-ede3-cbc -nosalt -pass pass:"_X1_X2 |
| 73 | ; N CALL S CALL="openssl enc -bf-cbc -nosalt -pass pass:"_X1_X2 |
| 74 | ; N CALL S CALL="openssl enc -a -rc4 -nosalt -pass pass:"_X1_X2 |
| 75 | N DEVICE S DEVICE="encryptionPipe" |
| 76 | N OLDIO S OLDIO=$IO |
| 77 | OPEN DEVICE:(shell="/bin/sh":comm=CALL)::"PIPE" |
| 78 | USE DEVICE |
| 79 | WRITE X,/EOF ; Write the string to encrypt |
| 80 | N I,OUTPUT ; I = counter. OUTPUT = encyrpted tems |
| 81 | FOR I=1:1 READ OUTPUT(I) Q:$ZEOF ; Read it into Output Array |
| 82 | U OLDIO |
| 83 | CLOSE DEVICE |
| 84 | ; Next two lines: concatentate the array into the root node |
| 85 | S OUTPUT="" |
| 86 | F I=1:1 Q:'$D(OUTPUT(I)) S OUTPUT=OUTPUT_OUTPUT(I) K OUTPUT(I) |
| 87 | ; X is the output from the API |
| 88 | S X=OUTPUT |
| 89 | QUIT |
| 90 | ; |
| 91 | DE ; DECRYPT |
| 92 | Q:'$D(X)!('$D(X1))!('$D(X2)) Q:'$L(X) |
| 93 | ; Expect X, X1, X2 |
| 94 | ; X is the string to encrypt. X1 and X2 are salts/password |
| 95 | ; X1 can be the DUZ |
| 96 | ; X2 can be the checksum of the text to encrypt |
| 97 | ; Output: X, the decrypted string. Length is the same the input. |
| 98 | ; Maximum supported length is maximum global node length. |
| 99 | ; Encrypting word processing fields is not supported. |
| 100 | N CALL S CALL="openssl enc -d -a -aes-256-cbc -nosalt -pass pass:"_X1_X2 |
| 101 | ; N CALL S CALL="openssl enc -a -d -rc4 -nosalt -pass pass:"_X1_X2 |
| 102 | N DEVICE S DEVICE="decryptionPipe" |
| 103 | N OLDIO S OLDIO=$IO |
| 104 | OPEN DEVICE:(shell="/bin/sh":comm=CALL)::"PIPE" |
| 105 | USE DEVICE |
| 106 | F W $E(X,1,64),! S X=$E(X,65,1024*1024*1024) Q:X="" ; Write Input base64 style |
| 107 | WRITE /EOF |
| 108 | N OUTPUT R OUTPUT:1 ; Read Output of decryption back. |
| 109 | U OLDIO |
| 110 | CLOSE DEVICE |
| 111 | S X=OUTPUT ; X is output |
| 112 | QUIT |
| 113 | ; |
| 114 | RUNTESTS S IO=$P S DIQUIET=1 D DT^DICRW D:$L($T(EN^XTMUNIT)) EN^XTMUNIT($T(+0),1) QUIT |
| 115 | THASH ; @TEST - Test Hashing |
| 116 | N DUZ |
| 117 | S DUZ=1 N X S X="HELLO WORLD" D HASH |
| 118 | N RESULT1 S RESULT1=X |
| 119 | S DUZ=1 N X S X="HELLO WORLD" D HASH |
| 120 | N RESULT2 S RESULT2=X |
| 121 | D CHKEQ^XTMUNIT(RESULT1,RESULT2,"Hash results are not equal") |
| 122 | ; |
| 123 | S DUZ=1 N X S X="HELLO WORLD" D HASH |
| 124 | N RESULT1 S RESULT1=X |
| 125 | S DUZ=2 N X S X="HELLO WORLD" D HASH |
| 126 | N RESULT2 S RESULT2=X |
| 127 | D CHKTF^XTMUNIT(RESULT1'=RESULT2,"Hash results are not supposed to be equal") |
| 128 | ; |
| 129 | S DUZ=1 |
| 130 | N X S X="Hello World" D HASH |
| 131 | N RESULT1 S RESULT1=X |
| 132 | N X S X="HELLO WORLD" D HASH |
| 133 | N RESULT2 S RESULT2=X |
| 134 | D CHKEQ^XTMUNIT(RESULT1,RESULT2,"Hash results of different cases aren't equal") |
| 135 | QUIT |
| 136 | ; |
| 137 | THASH2 ; @TEST - Test Hashing using main calling routine XUSHSHP |
| 138 | N DUZ |
| 139 | S DUZ=1 N X S X="HELLO WORLD" D HASH^XUSHSHP |
| 140 | N RESULT1 S RESULT1=X |
| 141 | S DUZ=1 N X S X="HELLO WORLD" D HASH^XUSHSHP |
| 142 | N RESULT2 S RESULT2=X |
| 143 | D CHKEQ^XTMUNIT(RESULT1,RESULT2,"Hash results are not equal") |
| 144 | ; |
| 145 | S DUZ=1 N X S X="HELLO WORLD" D HASH^XUSHSHP |
| 146 | N RESULT1 S RESULT1=X |
| 147 | S DUZ=2 N X S X="HELLO WORLD" D HASH^XUSHSHP |
| 148 | N RESULT2 S RESULT2=X |
| 149 | D CHKTF^XTMUNIT(RESULT1'=RESULT2,"Hash results are not supposed to be equal") |
| 150 | ; |
| 151 | S DUZ=1 |
| 152 | N X S X="Hello World" D HASH^XUSHSHP |
| 153 | N RESULT1 S RESULT1=X |
| 154 | N X S X="HELLO WORLD" D HASH^XUSHSHP |
| 155 | N RESULT2 S RESULT2=X |
| 156 | D CHKEQ^XTMUNIT(RESULT1,RESULT2,"Hash results of different cases aren't equal") |
| 157 | QUIT |
| 158 | ; |
| 159 | TENC ; @TEST - Test Encryption |
| 160 | N VALUE S VALUE="Mary has a little lamb" |
| 161 | S X=VALUE,X1=1,X2=234234234 |
| 162 | D EN,DE ; encrypt, decrypt X |
| 163 | D CHKEQ^XTMUNIT(VALUE,X,"Encryption and decryption didn't happen properly") |
| 164 | ; |
| 165 | N VALUE2 S VALUE2="Mary has a little lamb" |
| 166 | S X=VALUE2,X1=88,X2=234234234 |
| 167 | D EN ; encrypt |
| 168 | N ENCSTR1 S ENCSTR1=X |
| 169 | S X=VALUE2,X1=1,X2=234234234 ; Different X1 |
| 170 | D EN ; encrypt |
| 171 | N ENCSTR2 S ENCSTR2=X |
| 172 | D CHKTF^XTMUNIT(ENCSTR1'=ENCSTR2,"Encrypted strings with different passwords are not supposed to be equal") |
| 173 | QUIT |
| 174 | ; |
| 175 | TENC2 ; @TEST - Test Encryption by calling XUSHSHP |
| 176 | N VALUE S VALUE="Mary has a little lamb" |
| 177 | S X=VALUE,X1=1,X2=234234234 |
| 178 | D EN^XUSHSHP,DE^XUSHSHP ; encrypt, decrypt X |
| 179 | D CHKEQ^XTMUNIT(VALUE,X,"Encryption and decryption didn't happen properly") |
| 180 | ; |
| 181 | N VALUE2 S VALUE2="Mary has a little lamb" |
| 182 | S X=VALUE2,X1=88,X2=234234234 |
| 183 | D EN^XUSHSHP ; encrypt |
| 184 | N ENCSTR1 S ENCSTR1=X |
| 185 | S X=VALUE2,X1=1,X2=234234234 ; Different X1 |
| 186 | D EN^XUSHSHP ; encrypt |
| 187 | N ENCSTR2 S ENCSTR2=X |
| 188 | D CHKTF^XTMUNIT(ENCSTR1'=ENCSTR2,"Encrypted strings with different passwords are not supposed to be equal") |
| 189 | QUIT |
| 190 | LENGTH ; @TEST - Test Lengths |
| 191 | N X,X1,X2,I |
| 192 | S (X1,X2)=982734987234 |
| 193 | W ! |
| 194 | F I=1:1:60 K X S $P(X,"A",I)="A" W $L(X) D EN W ?30,$L(X),! |
| 195 | QUIT |
| 196 | }}} |