HMAC SHA1 – Java, Python and PHP

Generating a consistent HMAC SHA1 across multiple languages and mirror the java byte array (byte[]) mechanism.

Java Code

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class Signer {
    public static void main(String[] args) throws Exception {
        String key = "0f2100e34b54d50fd0138f300d3497579dae5279";
        String data = "secret-message";
        byte[] decodedKey = Hex.decodeHex(key.toCharArray());
        SecretKeySpec keySpec = new SecretKeySpec(decodedKey, "HmacSHA1");
        Mac mac = Mac.getInstance("HmacSHA1");
        mac.init(keySpec);
        byte[] dataBytes = data.getBytes("UTF-8");
        byte[] signatureBytes = mac.doFinal(dataBytes);
        String signature = new String(Base64.encodeBase64(signatureBytes), "UTF-8");
        System.out.println("key = " + key);
        System.out.println("data = " + data);
        System.out.println("signature = " + signature);
    }
}

PHP Equivalent

<?php
  $key = "0f2100e34b54d50fd0138f300d3497579dae5279";
  $data = "secret-message";
  $decodedKey = pack("H*", $key);
  $hmac = hash_hmac("sha1", $data, $decodedKey, TRUE);
  $signature = base64_encode($hmac);
  echo "key = $key\n";
  echo "data = $data\n";
  echo "signature = $signature";
?>

Python Equivalent

import hmac
import hashlib
key = "0f2100e34b54d50fd0138f300d3497579dae5279"
data = "secret-message"
decodedKey = key.decode("hex")
hmac = hmac.new(decodedKey, data.encode('UTF-8'), hashlib.sha1)
signature = hmac.digest().encode('base64')
print "key =", key
print "data =", data
print "signature =", signature

Expected Output

key = 0f2100e34b54d50fd0138f300d3497579dae5279
data = secret-message
signature = MhzlxM4a2htRhimCU/fXNBDBWaU=

Heartbleed nginx check

Few quick commands to check nginx has been patched succesfully for heartbleed.

# check nginx compile config
$ /opt/nginx/sbin/nginx -V
nginx version: nginx/1.4.0
built by gcc 4.7.2 (Debian 4.7.2-5) 
TLS SNI support enabled
configure arguments: --prefix=/opt/nginx --with-http_ssl_module --with-pcre=/opt/nginx/pcre-8.32 --with-zlib=/opt/nginx/zlib-1.2.8

# check which ssl library
$ ldd /opt/nginx/sbin/nginx | grep ssl
	libssl.so.1.0.0 => /usr/lib/x86_64-linux-gnu/libssl.so.1.0.0 (0x00007f489cd5a000)

$ strings /usr/lib/x86_64-linux-gnu/libssl.so.1.0.0 | grep "^OpenSSL "
OpenSSL 1.0.1e 11 Feb 2013

# check full ssl version (including when it was built)
$ openssl version -a
OpenSSL 1.0.1e 11 Feb 2013
built on: Tue Apr  8 08:49:19 UTC 2014
platform: debian-amd64
options:  bn(64,64) rc4(16x,int) des(idx,cisc,16,int) blowfish(idx) 
compiler: gcc -fPIC -DOPENSSL_PIC -DZLIB -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -m64 -DL_ENDIAN -DTERMIO -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -Wl,-z,relro -Wa,--noexecstack -Wall -DMD32_REG_T=int -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM
OPENSSLDIR: "/usr/lib/ssl"

# check changelog for note regarding CVE-2014-0160 patch
$ aptitude changelog openssl
openssl (1.0.1e-2+deb7u5) wheezy-security; urgency=high

  * Non-maintainer upload by the Security Team.
  * Add CVE-2014-0160.patch patch.
    CVE-2014-0160: Fix TLS/DTLS hearbeat information disclosure.
    A missing bounds check in the handling of the TLS heartbeat extension
    can be used to reveal up to 64k of memory to a connected client or
    server.

Download script

Just a little script to download files from my remote server and if need be unrar the files.

#!/bin/bash
LOCAL="/opt/files"
UNRAR="$LOCAL/extract"
LOG="$LOCAL/download.log"
REMOTE="server.com.au:path/to/files"
INPUT=$2

function init() {
  # create required directories
  [ ! -d "$LOCAL" ] && mkdir $LOCAL && echo "created $LOCAL"
  [ ! -d "$UNRAR" ] && mkdir $UNRAR && echo "created $UNRAR"
}

function download() {
  # append wildcard to input
  [ -n "$INPUT" ] && INPUT="${INPUT}*" && echo "Downloading $INPUT"
  [ -z "$INPUT" ] && INPUT="*" && echo "Downloading all files"
  # rsync files from remote server to local folder
  rsync -a --quiet --compress --log-file="$LOG" $REMOTE/$INPUT $LOCAL/ >> $LOG 2>&1 &
}

function unrar() {
  echo "Extracting *.rar files to $UNRAR"
  # unrar convert filenames to lower case, exclude paths and do not overwrite
  find $LOCAL -name "*.rar" -exec unrar x -cl -ep -o- {} $UNRAR \; >> $LOG 2>&1 &
}

init
case "$1" in
  download|d)
    download
    ;;
  unrar|u)
    unrar
    ;;
  both|b)
    download
    unrar
    ;;
  *)
    echo "Usage: $0 {download|unrar|both}"
esac

Tethering to Android Phone for Internet via Bluetooth

As mentioned earlier until I purchase a usb dongle I am running without a network. Just for kicks though I decided to setup tethering via bluetooth with my android phone. Which allows me to update packages etc without having to plug the raspberry pi into a network point.

Bluetooth Pairing

To make it a little easier I paired to raspberry pi from my phone.

# to check the raspberry pi bluetooth name
$ sudo hciconfig hci0 name

# to set the bluetooth name
$ sudo hciconfig hci0 name raspberrypi

# make the raspberry pi discoverable
$ sudo hciconfig hci0 piscan

# setup agent to listen for pairing request
$ sudo bluetooth-agent 12345
# from my phone I connected to raspberrpi-0 and confirmed code was displayed
Confirmation request of 7654321 fir device /org/bluez/1936/hci0/dev_0E_C9_35_42_E6_E9
[Ctrl-C]

# turn of discoverable
$ sudo hciconfig hci0 noscan

# check connected devices
# list currently connected bluetooth devices
$ sudo bluez-test-device list
BC:B0:0B:47:57:A8 matt’s keyboard
FA:C7:48:46:47:33 Logitech Bluetooth Mouse M555b
0E:C9:35:42:E6:E9 Galaxy Nexus

Setup Tethering

To tether to android phone for internet we need a little more configuration

# package required for 'pand' command
$ sudo apt-get install bluez-compat

# connect to phone and sets up network interface
$ sudo pand --connect 0E:C9:35:42:E6:E9 -n

# show networks
$ ifconfig
bnep0     Link encap:Ethernet  HWaddr 00:4d:9c:2a:47:94  
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:12 (12.0 B)  TX bytes:60 (60.0 B)
...

# set dhclient to use bnep0 
$ sudo dhclient bnep0

# test internet connectivity
$ ping www.google.com
PING www.google.com (74.125.237.145) 56(84) bytes of data.
64 bytes from syd01s13-in-f17.1e100.net (74.125.237.145): icmp_req=1 ttl=52 time=26.3 ms
64 bytes from syd01s13-in-f17.1e100.net (74.125.237.145): icmp_req=2 ttl=52 time=26.6 ms

Turning off tethering

To turn of tethering and unconfigure the PAN network

# release bnep0 dhclient
$ sudo dhclient -r bnep0

# disconnect pan
$sudo pand -K

Create an alias to make this tethering easy peasy

As I’ll probably turn tethering on and off lots of times I put all this into an alias

$ vi ~/.bash_aliases
alias leash='sudo pand --connect 0E:C9:35:42:E6:E9 -n && sudo dhclient bnep0'
alias unleash='sudo dhclient -r bnep0 && sudo pand -K'

After reloading bash I can simply type the following to tether or untether

$ leash
$ unleash

If you haven’t already got it installed you should also put Power Toggles on your phone so you can quickly turn wifi / bluetooth tethering on and off.

USB Bluetooth dongle and keyboard

As I am running my raspberry pi without a network (until I can grab a usb wifi dongle) I’m using a spare usb bluetooth dongle and bluetooth keyboard I had lying around.

Bluetooth Installation

$ sudo apt-get install bluez python-gobject

# check bluetooth dongle it recognised
$ hcitool dev
Devices:
	hci0	7B:13:75:FD:11:EB

# scan for discoverable devices
$ hcitool scan
Scanning ...
	BC:B0:0B:47:57:A8	matt’s keyboard
	FA:C7:48:46:47:33	Logitech Bluetooth Mouse M555b

# pair with keyboard
$ sudo bluez-simple-agent hci0 BC:B0:0B:47:57:A8
RequestPinCode (/org/bluez/3465/hci0/dev_BC_B0_0B_47_57_A8)
Enter PIN Code: 12345
# type pin + enter on keyboard
Release
New device (/org/bluez/3465/hci0/dev_BC_B0_0B_47_57_A8)

# pair with mouse
$ sudo bluez-simple-agent hci0 FA:C7:48:46:47:33
RequestPinCode (/org/bluez/2015/hci0/dev_FA_C7_48_46_47_33)
Enter PIN Code: 0000
Release
New device (/org/bluez/2015/hci0/dev_FA_C7_48_46_47_33)

# add devices to trusted list and connect
$ sudo bluez-test-device trusted BC:B0:0B:47:57:A8 yes
$ sudo bluez-test-device trusted FA:C7:48:46:47:33 yes
$ sudo bluez-test-input connect BC:B0:0B:47:57:A8 yes
$ sudo bluez-test-input connect FA:C7:48:46:47:33 yes

# reboot and test if keyboard connects
$ sudo shutdown -r now

# list currently connected bluetooth devices
$ sudo bluez-test-device list
BC:B0:0B:47:57:A8 matt’s keyboard
FA:C7:48:46:47:33 Logitech Bluetooth Mouse M555b

As I’m using an apple wireless keyboard I needed to jump into raspi-config and reconfigure my keyboard settings

$ sudo raspi-config
# 3 - Internationalisation Options
# I3 - Change Keyboard Layout (wait a little for it to load)
# set keyboard to Apple Aluminium Keyboard (ANSI) and default options for rest of prompts

Raspbian Install

Load Raspbian Image onto SD Card

Installation was done using OSX terminal and a 16 GB SD Card (class 10).

  • Download latest Raspbian
  • Insert SD Card and open terminal
$ df -h
Filesystem      Size   Used  Avail Capacity  iused    ifree %iused  Mounted on
/dev/disk2s1    15Gi  2.1Mi   15Gi     1%        0        0  100%   /Volumes/UNTITLED

$ diskutil unmount /dev/disk2s1
$ unzip 2013-09-25-wheezy-raspbian.zip

$ sudo dd if=2013-09-25-wheezy-raspbian.img of=/dev/rdisk2 bs=1m
# note: dd does not output anything until it finishes just be patient
2825+0 records in
2825+0 records out
2962227200 bytes transferred in 295.230490 secs (10033609 bytes/sec)

$ diskutil eject /dev/disk2s1

Thats it stick the sd card into the raspberry pi and turn it on.

For those who are curious:

Why am I using /dev/rdisk2 and not /dev/disk2? rdisk is a raw path, which is faster.

I tested it to see how much faster (it wasn’t worth the wait):
5 minutes using /dev/rdisk2 vs 25 minutes using /dev/disk2

Initial Config

Now that we have the raspberry pi booted up time to ssh in and configure a few basic things.

$ ssh pi@192.168.1.2

# set your local time.
$ sudo dpkg-reconfigure tzdata

# update package list and upgrade to latest
$ sudo apt-get update && sudo apt-get upgrade

# configure raspberry
$ sudo raspi-config
# expand filesystem to fill sd card
# change the default password (raspberry) to something else

# reboot
$ sudo shutdown -r now && exit