Howto:Encrypt or Decrypt PBX user passwords
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
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) {
$r = "";
for ($i = 16; $i > 0; $i--) $r .= sprintf("%02x", ord($bin[16-$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
// get crypt class
$crypt = new rc4crypt();
// convert admin key hex string to binary
$binkey = pack('H*', $pbxKey);
// convert pbx pw to rc4 seed
$pbxPWKey = rc4crypt::make_pbx_key($pbxPW);
// convert user password to rc4 data buffer
$pbxUserpwKey = rc4crypt::make_pbx_key($userpw);
// decrypt the pbx key
$pbxKeyDecrypted = $crypt->decrypt($pbxPWKey, $binkey, false);
// encrypt the user password
$cryptedUserPW = $crypt->encrypt($pbxKeyDecrypted, $pbxUserpwKey, false);
// output
table(
array(
array("Item", "Value"),
array("_ADMIN_'s key attribute (given)", $pbxKey),
array("PBX Password in cleare (given)", $pbxPW),
array("User Password (given)", $userpw),
array("PBX key (decrypted)", hexprint($pbxKeyDecrypted)),
array("User PW (encrypted)", hexprint($cryptedUserPW)),
)
);
?>
The RC4 encryption class:
<?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) {
// create special key format, 16bytes null padded pwd
$key = $pwd;
for ($i = strlen($pwd); $i < 16; $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);
}
}
?>