Howto:Encrypt or Decrypt PBX user passwords: Difference between revisions
Line 86: | Line 86: | ||
If you do not want to use rc4.exe, here is sample code in PHP. It is to be called like | If you do not want to use rc4.exe, here is sample code in PHP. It is to be called like | ||
<code>http://localhost:8080/web/tools/config/config-local/config/init/encrypt-pbx-user-pw.php?pbxpw=pwd&pbxkey=566e2a2f1d259e4136046d5cbacaea9f&userpw=secret</code> | <code>http://localhost:8080/web/tools/config/config-local/config/init/encrypt-pbx-user-pw.php?pbxpw=pwd&pbxkey=566e2a2f1d259e4136046d5cbacaea9f&userpw=secret&version=10</code> | ||
encrypt-pbx-user-pw.php: | encrypt-pbx-user-pw.php: | ||
<code php> | <code php> | ||
<?php | <?php | ||
Line 102: | Line 101: | ||
// utilities | // utilities | ||
function hexprint($bin) { | function hexprint($bin, $nbytes = 0) { | ||
if ($nbytes == 0) | |||
$nbytes = strlen($bin); | |||
$r = ""; | $r = ""; | ||
for ($i = | for ($i = $nbytes; $i > 0; $i--) | ||
$r .= sprintf("%02x", ord($bin[$nbytes - $i])); | |||
return $r; | return $r; | ||
} | } | ||
function tablerow(array $data, $type = "td") { | function tablerow(array $data, $type = "td") { | ||
print "<tr>"; | print "<tr>"; | ||
foreach ($data as $item) print "<$type>" . htmlspecialchars ($item) . "</$type>"; | foreach ($data as $item) | ||
print "<$type>" . htmlspecialchars($item) . "</$type>"; | |||
print "</tr>"; | print "</tr>"; | ||
} | } | ||
function table(array $data) { | function table(array $data) { | ||
print "<table><thead>"; | print "<table><thead>"; | ||
tablerow(array_shift($data), "th"); | tablerow(array_shift($data), "th"); | ||
print "</thead>"; | print "</thead>"; | ||
print "<tbody>"; | print "<tbody>"; | ||
foreach ($data as $row) tablerow($row); | foreach ($data as $row) | ||
tablerow($row); | |||
print "</tbody></table>"; | print "</tbody></table>"; | ||
} | } | ||
Line 124: | Line 130: | ||
$pbxPW = $_REQUEST['pbxpw']; // clear text pbx password | $pbxPW = $_REQUEST['pbxpw']; // clear text pbx password | ||
$userpw = $_REQUEST['userpw']; // user password in clear to encrypt | $userpw = $_REQUEST['userpw']; // user password in clear to encrypt | ||
$version = empty($_REQUEST['version']) ? 8 : (int) $_REQUEST['version']; | |||
// get crypt class | // get crypt class | ||
$crypt = new rc4crypt(); | $crypt = new rc4crypt(); | ||
// convert admin key hex string to binary | // convert admin key hex string to binary | ||
$binkey = pack('H*', $pbxKey); | $binkey = pack('H*', $pbxKey); | ||
// convert pbx pw to rc4 seed | // convert pbx pw to rc4 seed (this is a 16byte input key) | ||
$pbxPWKey = rc4crypt::make_pbx_key($pbxPW); | $pbxPWKey = rc4crypt::make_pbx_key($pbxPW); | ||
// convert user password to rc4 data buffer | // convert user password to rc4 data buffer (this is 16 byte prev7, 24 byte later input key) | ||
$pbxUserpwKey = rc4crypt::make_pbx_key($userpw); | $pbxUserpwKey = rc4crypt::make_pbx_key($userpw, $version < 7 ? 16 : 24); | ||
// decrypt the pbx key | // decrypt the pbx key | ||
Line 141: | Line 147: | ||
// output | // output | ||
print "<body style='font-family: courier'>"; | |||
table( | table( | ||
array( | array( | ||
array("Item", "Value"), | array("Item", "Value"), | ||
array("_ADMIN_'s key attribute (given)", $pbxKey), | array("_ADMIN_'s key attribute (given)", $pbxKey), | ||
array("PBX Password in | array("PBX Password in clear (given)", $pbxPW), | ||
array("PBX Password in hex", hexprint($pbxPW)), | |||
array("PBX Password hex zero filled", hexprint($pbxPWKey)), | |||
array("User Password (given)", $userpw), | array("User Password (given)", $userpw), | ||
array("User Password hex zero filled", hexprint($pbxUserpwKey)), | |||
array("PBX key (decrypted)", hexprint($pbxKeyDecrypted)), | array("PBX key (decrypted)", hexprint($pbxKeyDecrypted)), | ||
array("User PW (encrypted)", hexprint($cryptedUserPW)), | |||
) | |||
); | |||
print "</body>"; | |||
?> | ?> | ||
</code> | </code> | ||
Line 159: | Line 168: | ||
<code php> | <code php> | ||
<?php | |||
<?php | <?php | ||
Line 211: | Line 221: | ||
* @return string | * @return string | ||
*/ | */ | ||
function make_pbx_key($pwd) { | function make_pbx_key($pwd, $size = 16) { | ||
// create special key format, 16bytes null padded pwd | // create special key format, 16bytes (default) null padded pwd | ||
$key = $pwd; | $key = $pwd; | ||
for ($i = strlen($pwd); $i < | for ($i = strlen($pwd); $i < $size; $i++) { | ||
$key .= "\0"; | $key .= "\0"; | ||
} | } | ||
Line 280: | Line 290: | ||
} | } | ||
?> | ?> | ||
</code> | </code> | ||
Revision as of 18:21, 29 January 2014
Applies To
This information applies to
- all innovaphone PBX platforms, V6 and later
Abstract
Passwords of user objects in the PBX are saved in encrypted form in order to ensure confidentiality.
Sometimes it could be necessary to create user objects automatically without using the PBX's web gui.
Problem Details
The password attribute of an user object must be written encrypted, while all other attributes are plain text.
Example:
mod cmd FLASHDIR0 add-item 101 (cn=Venus) (pbx=<user filter="normal" cd-filter="normal" busy-in="65535" pwd="a50c0b9263f673a778f671fbf9e4358c"/>) (node=root) (loc=.) (e164=224) (h323=venus)
The user password needs to be encrypted using the PBX key.
The PBX key is automatically generated during activation of the PBX.
The PBX key can be found inside the _ADMIN_ object in encrypted form.
The PBX key is encrypted using the PBX password.
The PBX password has been configured by the administrator during activation of the PBX.
System Requirements
In order to manually generate PBX's user object with passwords:
- you need to know the PBX password
- you need the encrypted PBX key
- you need the encryption/decryption tool rc4.exe
rc4.exe is part of the tools folder of the V6 apps package available from the download page.
Usage
Getting the PBX key
First Step is getting the PBX key by decryting the key attribute of the _ADMIN_ object:
mod cmd FLASHDIR0 add-item 101 (cn=_ADMIN_) (h323=pbx-admin) (pbx=<filter name="normal"/>) (pbx=<filter name="unknown"/>) (pbx=<user pwd="a61e0ce0068273a778f671fbf9e4358c" key="566e2a2f1d259e4136046d5cbacaea9f"/>)
The PBX password in this case is "pwd". We need it in binary form here: 707764 (ascii values of each character in hex).
Use rc4.exe to decrypt the PBX key:
rc4.exe -d 707764 566e2a2f1d259e4136046d5cbacaea9f -> 7e6236c35d119afe62c0fd398d6f6175
The decrypted PBX key is 7e6236c35d119afe62c0fd398d6f6175.
Encrypting the user password
With the decrypted PBX key in hand you can start encrypting user passwords.
In this case we want to encrypt the passwort "secret":
rc4.exe -e 7e6236c35d119afe62c0fd398d6f6175 secret -> a50c0b9263f673a778f671fbf9e4358c
The encrypted user password is a50c0b9263f673a778f671fbf9e4358c.
This can be used to form a new (or update an existing) user object.
Notes
Do not mix-up the PBX password with the admin password!
The admin password is used together with the admin username to get access to the config gui of the device.
The admin username and password are set by default to "admin" and "ipxxxx" (depending on your device type).
The PBX password in opposite must always be configured manually during activation of the PBX.
Be sure of really knowing the correct PBX password.
This procedure does not work for all the passwords which are stored in vars, such as e.g. the devices admin password (vars create CMD0/AUTH
).
Use without rc4.exe
If you do not want to use rc4.exe, here is sample code in PHP. It is to be called like
http://localhost:8080/web/tools/config/config-local/config/init/encrypt-pbx-user-pw.php?pbxpw=pwd&pbxkey=566e2a2f1d259e4136046d5cbacaea9f&userpw=secret&version=10
encrypt-pbx-user-pw.php:
<?php
/*
* encrypt PBX user passwords
* call e.g. encrypt-pbx-user-pw.php?pbxpw=pwd&pbxkey=566e2a2f1d259e4136046d5cbacaea9f&userpw=secret
*/
require_once "classes/class.rc4crypt.php";
// utilities
function hexprint($bin, $nbytes = 0) {
if ($nbytes == 0)
$nbytes = strlen($bin);
$r = "";
for ($i = $nbytes; $i > 0; $i--)
$r .= sprintf("%02x", ord($bin[$nbytes - $i]));
return $r;
}
function tablerow(array $data, $type = "td") {
print "<tr>";
foreach ($data as $item)
print "<$type>" . htmlspecialchars($item) . "</$type>";
print "</tr>";
}
function table(array $data) {
print "<table><thead>";
tablerow(array_shift($data), "th");
print "</thead>";
print "<tbody>";
foreach ($data as $row)
tablerow($row);
print "</tbody></table>";
}
$pbxKey = $_REQUEST['pbxkey']; // pbx key as taken vom _ADMIN_'s key= attribute (hex-string)
$pbxPW = $_REQUEST['pbxpw']; // clear text pbx password
$userpw = $_REQUEST['userpw']; // user password in clear to encrypt
$version = empty($_REQUEST['version']) ? 8 : (int) $_REQUEST['version'];
// get crypt class
$crypt = new rc4crypt();
// convert admin key hex string to binary
$binkey = pack('H*', $pbxKey);
// convert pbx pw to rc4 seed (this is a 16byte input key)
$pbxPWKey = rc4crypt::make_pbx_key($pbxPW);
// convert user password to rc4 data buffer (this is 16 byte prev7, 24 byte later input key)
$pbxUserpwKey = rc4crypt::make_pbx_key($userpw, $version < 7 ? 16 : 24);
// decrypt the pbx key
$pbxKeyDecrypted = $crypt->decrypt($pbxPWKey, $binkey, false);
// encrypt the user password
$cryptedUserPW = $crypt->encrypt($pbxKeyDecrypted, $pbxUserpwKey, false);
// output
print "<body style='font-family: courier'>";
table(
array(
array("Item", "Value"),
array("_ADMIN_'s key attribute (given)", $pbxKey),
array("PBX Password in clear (given)", $pbxPW),
array("PBX Password in hex", hexprint($pbxPW)),
array("PBX Password hex zero filled", hexprint($pbxPWKey)),
array("User Password (given)", $userpw),
array("User Password hex zero filled", hexprint($pbxUserpwKey)),
array("PBX key (decrypted)", hexprint($pbxKeyDecrypted)),
array("User PW (encrypted)", hexprint($cryptedUserPW)),
)
);
print "</body>";
?>
The RC4 encryption class:
<?php
<?php
/* vim: set expandtab shiftwidth=4 softtabstop=4 tabstop=4: */
/**
* RC4Crypt 3.2
*
* RC4Crypt is a petite library that allows you to use RC4
* encryption easily in PHP. It's OO and can produce outputs
* in binary and hex.
*
* (C) Copyright 2006 Mukul Sabharwal [http://mjsabby.com]
* All Rights Reserved
*
* @link http://rc4crypt.devhome.org
* @author Mukul Sabharwal <mjsabby@gmail.com>
* @version $Id: class.rc4crypt.php,v 3.2 2006/03/10 05:47:24 mukul Exp $
* @copyright Copyright © 2006 Mukul Sabharwal
* @license http://www.gnu.org/copyleft/gpl.html
* @package RC4Crypt
*/
/**
* RC4 Class
* @package RC4Crypt
*/
class rc4crypt {
/**
* inno specific key creator for keys derived from user/password
* @param string $user
* @param string $password
* @return string
*/
static function make_key($user, $password) {
// create special key format, 16bytes null padded user + 16 byets null padded password
$key = $user;
for ($i = strlen($user); $i < 16; $i++) {
$key .= "\0";
}
$key .= $password;
for ($i = strlen($password); $i < 16; $i++) {
$key .= "\0";
}
return $key;
}
/**
* inno specific key creator for keys derived from password only
* @param string $pwd
* @return string
*/
function make_pbx_key($pwd, $size = 16) {
// create special key format, 16bytes (default) null padded pwd
$key = $pwd;
for ($i = strlen($pwd); $i < $size; $i++) {
$key .= "\0";
}
return $key;
}
/**
* The symmetric encryption function
*
* @param string $pwd Key to encrypt with (can be binary of hex)
* @param string $data Content to be encrypted
* @param bool $ispwdHex Key passed is in hexadecimal or not
* @access public
* @return string
*/
function encrypt ($pwd, $data, $ispwdHex = 0)
{
if ($ispwdHex)
$pwd = @pack('H*', $pwd); // valid input, please!
$key[] = '';
$box[] = '';
$cipher = '';
$pwd_length = strlen($pwd);
$data_length = strlen($data);
for ($i = 0; $i < 256; $i++)
{
$key[$i] = ord($pwd[$i % $pwd_length]);
$box[$i] = $i;
}
for ($j = $i = 0; $i < 256; $i++)
{
$j = ($j + $box[$i] + $key[$i]) % 256;
$tmp = $box[$i];
$box[$i] = $box[$j];
$box[$j] = $tmp;
}
for ($a = $j = $i = 0; $i < $data_length; $i++)
{
$a = ($a + 1) % 256;
$j = ($j + $box[$a]) % 256;
$tmp = $box[$a];
$box[$a] = $box[$j];
$box[$j] = $tmp;
$k = $box[(($box[$a] + $box[$j]) % 256)];
$cipher .= chr(ord($data[$i]) ^ $k);
}
return $cipher;
}
/**
* Decryption, recall encryption
*
* @param string $pwd Key to decrypt with (can be binary of hex)
* @param string $data Content to be decrypted
* @param bool $ispwdHex Key passed is in hexadecimal or not
* @access public
* @return string
*/
function decrypt ($pwd, $data, $ispwdHex = 0)
{
return rc4crypt::encrypt($pwd, $data, $ispwdHex);
}
}
?>