Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sergeycherepanov/fda6ba001812647180f530aa193f898d to your computer and use it in GitHub Desktop.
Save sergeycherepanov/fda6ba001812647180f530aa193f898d to your computer and use it in GitHub Desktop.
WSSE OroCRM Auth PHP/JS
<pre>
<?php
$username = 'admin';
$key = 'd525e743ee692632b52a05570444aa537e06a8cc';
$created = date('c');
$nonce = substr(md5(time()), 0, 16);
$sha1 = sha1($nonce . $created . $key, true);
$digest = base64_encode($sha1);
echo "user: {$username}" . PHP_EOL;
echo "key: {$key}" . PHP_EOL;
echo "created: {$created}" . PHP_EOL;
echo "nonce: {$nonce}" . PHP_EOL;
echo "sha1: {$sha1}" . PHP_EOL;
echo "digest: {$digest}" . PHP_EOL . PHP_EOL;
echo ("HEADERS: ") . PHP_EOL;
echo ('Authorization: WSSE profile="UsernameToken"') . PHP_EOL;
echo PHP_EOL;
echo "--------------";
echo PHP_EOL;
echo sprintf(
'X-WSSE: UsernameToken Username="%s", PasswordDigest="%s", Nonce="%s", Created="%s"',
$username,
$digest,
base64_encode($nonce),
$created
);
$opts = array(
'http'=>array(
'method'=>"GET",
'header'=>'Authorization: WSSE profile="UsernameToken"' . PHP_EOL .
sprintf(
'X-WSSE: UsernameToken Username="%s", PasswordDigest="%s", Nonce="%s", Created="%s"' . PHP_EOL,
$username,
$digest,
base64_encode($nonce),
$created
)
)
);
$context = stream_context_create($opts);
echo file_get_contents('https://orocrm.loc/api/rest/latest/users', false, $context);
?>
</pre>
<script type="text/javascript">
// Encodes data with MIME base64
function base64_encode( data ) {
//
// + original by: Tyler Akins (http://rumkin.com)
// + improved by: Bayron Guevara
var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var o1, o2, o3, h1, h2, h3, h4, bits, i=0, enc='';
do { // pack three octets into four hexets
o1 = data.charCodeAt(i++);
o2 = data.charCodeAt(i++);
o3 = data.charCodeAt(i++);
bits = o1<<16 | o2<<8 | o3;
h1 = bits>>18 & 0x3f;
h2 = bits>>12 & 0x3f;
h3 = bits>>6 & 0x3f;
h4 = bits & 0x3f;
// use hexets to index into b64, and append result to encoded string
enc += b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);
} while (i < data.length);
switch( data.length % 3 ){
case 1:
enc = enc.slice(0, -2) + '==';
break;
case 2:
enc = enc.slice(0, -1) + '=';
break;
}
return enc;
}
window.sha1 = (function() {
/*
* A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
* in FIPS 180-1
* Version 2.2 Copyright Paul Johnston 2000 - 2009.
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
* Distributed under the BSD License
* See http://pajhome.org.uk/crypt/md5 for details.
*/
// Convert a raw string to a hex string
function rawToHex(raw) {
var hex = "";
var hexChars = "0123456789abcdef";
for (var i = 0; i < raw.length; i++) {
var c = raw.charCodeAt(i);
hex += (
hexChars.charAt((c >>> 4) & 0x0f) +
hexChars.charAt(c & 0x0f));
}
return hex;
}
// Calculate the SHA1 of a raw string
function sha1Raw(raw) {
return binaryToRaw(sha1Binary(rawToBinary(raw), raw.length * 8));
}
/*
* Convert an array of big-endian words to a string
*/
function binaryToRaw(bin) {
var raw = "";
for (var i = 0, il = bin.length * 32; i < il; i += 8) {
raw += String.fromCharCode((bin[i >> 5] >>> (24 - i % 32)) & 0xff);
}
return raw;
}
/*
* Calculate the SHA-1 of an array of big-endian words, and a bit length
*/
function sha1Binary(bin, len) {
// append padding
bin[len >> 5] |= 0x80 << (24 - len % 32);
bin[((len + 64 >> 9) << 4) + 15] = len;
var w = new Array(80);
var a = 1732584193;
var b = -271733879;
var c = -1732584194;
var d = 271733878;
var e = -1009589776;
for (var i = 0, il = bin.length; i < il; i += 16) {
var _a = a;
var _b = b;
var _c = c;
var _d = d;
var _e = e;
for (var j = 0; j < 80; j++) {
if (j < 16) {
w[j] = bin[i + j];
} else {
w[j] = _rotateLeft(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
}
var t = _add(_add(_rotateLeft(a, 5), _ft(j, b, c, d)),
_add(_add(e, w[j]), _kt(j)));
e = d;
d = c;
c = _rotateLeft(b, 30);
b = a;
a = t;
}
a = _add(a, _a);
b = _add(b, _b);
c = _add(c, _c);
d = _add(d, _d);
e = _add(e, _e);
}
return [a, b, c, d, e];
}
// Add integers, wrapping at 2^32. This uses 16-bit operations internally
// to work around bugs in some JS interpreters.
function _add(x, y) {
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
}
/*
* Bitwise rotate a 32-bit number to the left.
*/
function _rotateLeft(n, count) {
return (n << count) | (n >>> (32 - count));
}
/*
* Perform the appropriate triplet combination function for the current
* iteration
*/
function _ft(t, b, c, d) {
if (t < 20) {
return (b & c) | ((~b) & d);
} else if (t < 40) {
return b ^ c ^ d;
} else if (t < 60) {
return (b & c) | (b & d) | (c & d);
} else {
return b ^ c ^ d;
}
}
/*
* Determine the appropriate additive constant for the current iteration
*/
function _kt(t) {
if (t < 20) {
return 1518500249;
} else if (t < 40) {
return 1859775393;
} else if (t < 60) {
return -1894007588;
} else {
return -899497514;
}
}
// Convert a raw string to an array of big-endian words.
// Characters >255 have their high-byte silently ignored.
function rawToBinary(raw) {
var binary = new Array(raw.length >> 2);
for (var i = 0, il = binary.length; i < il; i++) {
binary[i] = 0;
}
for (i = 0, il = raw.length * 8; i < il; i += 8) {
binary[i>>5] |= (raw.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
}
return binary;
}
// Encode a string as UTF-8.
// For efficiency, this assumes the input is valid UTF-16.
function stringToRaw(string) {
var raw = "", x, y;
var i = -1;
var il = string.length;
while (++i < il) {
// decode UTF-16 surrogate pairs
x = string.charCodeAt(i);
y = i + 1 < il ? string.charCodeAt(i + 1) : 0;
if (0xd800 <= x && x <= 0xdbff && 0xdc00 <= y && y <= 0xdfff) {
x = 0x10000 + ((x & 0x03ff) << 10) + (y & 0x03ff);
++i;
}
// encode output as UTF-8
if (x <= 0x7f) {
raw += String.fromCharCode(x);
} else if (x <= 0x7ff) {
raw += String.fromCharCode(0xc0 | ((x >>> 6 ) & 0x1f),
0x80 | ( x & 0x3f));
} else if (x <= 0xffff) {
raw += String.fromCharCode(0xe0 | ((x >>> 12) & 0x0f),
0x80 | ((x >>> 6 ) & 0x3f),
0x80 | ( x & 0x3f));
} else if (x <= 0x1fffff) {
raw += String.fromCharCode(0xf0 | ((x >>> 18) & 0x07),
0x80 | ((x >>> 12) & 0x3f),
0x80 | ((x >>> 6 ) & 0x3f),
0x80 | ( x & 0x3f));
}
}
return raw;
}
// Calculate the HMAC-SHA1 of a key and some data (raw strings)
function hmacRaw(key, data) {
var binaryKey = rawToBinary(key);
if (binaryKey.length > 16) {
binaryKey = sha1Binary(binaryKey, key.length * 8);
}
var ipad = new Array(16);
var opad = new Array(16);
for(var i = 0; i < 16; i++) {
ipad[i] = binaryKey[i] ^ 0x36363636;
opad[i] = binaryKey[i] ^ 0x5c5c5c5c;
}
var hash = sha1Binary(ipad.concat(rawToBinary(data)), 512 + data.length * 8);
return binaryToRaw(sha1Binary(opad.concat(hash), 512 + 160));
}
var tests = {
hmac: {
"fbdb1d1b18aa6c08324b7d64b71fb76370690e1d":
["", ""],
"de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9":
["key", "The quick brown fox jumps over the lazy dog"]
},
sha1: {
"da39a3ee5e6b4b0d3255bfef95601890afd80709":
"",
"2fd4e1c67a2d28fced849ee1bb76e7391b93eb12":
"The quick brown fox jumps over the lazy dog",
}
};
return {
sha1Raw: function(s) {
return sha1Raw(stringToRaw(s));
},
sha1: function(s) {
return rawToHex(sha1Raw(stringToRaw(s)));
},
sha1Hex: function(value) {
return rawToHex(sha1Raw(this.hexToString(value)));
},
hmac: function(k, d) {
return rawToHex(hmacRaw(stringToRaw(k), stringToRaw(d)));
},
hexToString: function(hex) {
var str = '';
for (var i = 0, il = hex.length; i < il; i += 2) {
str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
}
return str;
},
test: function() {
var success = true;
for (var expectedOutput in tests.sha1) {
if (tests.sha1.hasOwnProperty(expectedOutput)) {
var input = tests.sha1[expectedOutput];
var output = this.sha1(input).toLowerCase();
if (output !== expectedOutput) {
console.error(
"sha1(" + input + ") was " + output +
" (expected: " + expectedOutput + ")");
success = false;
}
}
}
for (var expectedOutput in tests.hmac) {
if (tests.hmac.hasOwnProperty(expectedOutput)) {
var input = tests.hmac[expectedOutput];
var output = this.hmac(input[0], input[1]).toLowerCase();
if (output !== expectedOutput) {
console.error(
"hmac(" + input[0] + ", " + input[1] + ") was " + output +
" (expected: " + expectedOutput + ")");
success = false;
}
}
}
return success;
}
};
})();
function formatLocalDate() {
var now = new Date(),
tzo = -now.getTimezoneOffset(),
dif = tzo >= 0 ? '+' : '-',
pad = function(num) {
var norm = Math.abs(Math.floor(num));
return (norm < 10 ? '0' : '') + norm;
};
return now.getFullYear()
+ '-' + pad(now.getMonth()+1)
+ '-' + pad(now.getDate())
+ 'T' + pad(now.getHours())
+ ':' + pad(now.getMinutes())
+ ':' + pad(now.getSeconds())
+ dif + pad(tzo / 60)
+ ':' + pad(tzo % 60);
}
var username = 'admin';
var key = 'd525e743ee692632b52a05570444aa537e06a8cc';
var nonce = (Math.random().toString(36).substring(2) + Math.random().toString(36).substring(2)).substr(0, 16);
var created = formatLocalDate();
var shastr = sha1.sha1Raw(nonce + created + key);
var digest = base64_encode(shastr);
var str = "" + "\n" + "\n";
str += ( "user: " + username) + "\n";
str += ( "key: " + key) + "\n";
str += ( "created: " + created) + "\n";
str += ( "nonce: " + nonce) + "\n";
str += ( "sha1: " + shastr) + "\n";
str += ( "digest: " + digest) + "\n\n";
str += ("HEADERS: ") + "\n";
str += ('Authorization:WSSE profile="UsernameToken"') + "\n";
str += 'X-WSSE: UsernameToken Username="'+username+'", PasswordDigest="'+digest+'", Nonce="'+base64_encode(nonce)+'", Created="'+created+'"';
document.write("<pre>"+str+"</pre>")
// Postman rest api client
/**
postman.setGlobalVariable('wsse_authorization', 'WSSE profile="UsernameToken"');
postman.setGlobalVariable('xwsse', 'UsernameToken Username="'+username+'", PasswordDigest="'+digest+'", Nonce="'+base64_encode(nonce)+'", Created="'+created+'"');
**/
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment