一段JAVA签名算法的PHP改写
生活随笔
收集整理的這篇文章主要介紹了
一段JAVA签名算法的PHP改写
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
源代碼是這樣的:
public class AuthorizationSignature {public static String createSignature(String verb, String contentMD5, String contentType, String date,String canonicalizedSALHeaders, String canonicalizedResource) {String signatureStr = verb + "\\n" + contentMD5 + "\\n" + contentType + "\\n" + date + "\\n"+ canonicalizedSALHeaders + canonicalizedResource;signatureStr = java.net.URLDecoder.decode(signatureStr);HmacSHA1Signature hss = new HmacSHA1Signature();String toSignature = hss.computeSignature(AuthConfiguration.getInstance().getAuthConfigurationDTO().getSecretKey(), signatureStr);String authorization = AuthConfiguration.getInstance().getAuthConfigurationDTO().getEnterpriseHeader()+ AuthConfiguration.getInstance().getAuthConfigurationDTO().getAccessKey() + ":" + toSignature;return authorization;} }public class HmacSHA1Signature extends ServiceSignature {private static final Logger LOG = LoggerFactory.getLogger(HmacSHA1Signature.class);private static final String DEFAULT_CHARSET = "UTF-8";private static final String ALGORITHM = "HmacSHA1";@Overridepublic String getAlgorithm() {return ALGORITHM;}@Overridepublic String computeSignature(String key, String data) {byte[] signData = null;try {signData = signature(key.getBytes(DEFAULT_CHARSET), data.getBytes(DEFAULT_CHARSET));} catch (UnsupportedEncodingException ex) {LOG.debug(ex.getMessage());}return BinaryUtil.toBase64String(signData);}private byte[] signature(byte[] key, byte[] data) {try {Mac mac = Mac.getInstance(ALGORITHM);mac.init(new SecretKeySpec(key, ALGORITHM));return mac.doFinal(data);} catch (NoSuchAlgorithmException e1) {// throw new RuntimeException("Unsupported algorithm: HmacSHA1");LOG.error("Unsupported algorithm: HmacSHA1", e1);return null;} catch (InvalidKeyException e) {// throw new RuntimeException();LOG.debug(e.getMessage());return null;}} }
public class BinaryUtil {private static final Logger LOG = LoggerFactory.getLogger(BinaryUtil.class);public static String toBase64String(byte[] binaryData) {String toBase64Result = null;try {toBase64Result = new String(Base64.encodeBase64(binaryData), ContentUtil.BYTE_CODE);} catch (UnsupportedEncodingException e) {LOG.debug(e.getMessage());}return toBase64Result;}public static byte[] fromBase64String(String base64String) {byte[] fromBase64Result = null;try {fromBase64Result = Base64.decodeBase64(base64String.getBytes(ContentUtil.BYTE_CODE));} catch (UnsupportedEncodingException e) {LOG.debug(e.getMessage());}return fromBase64Result;} }
需要改寫為PHP代碼, 一步步分析, 首先是核心的MAC_SHA1簽名算法
Mac mac = Mac.getInstance(ALGORITHM);mac.init(new SecretKeySpec(key, ALGORITHM));return mac.doFinal(data);等效的PHP代碼是調用內建函數hash_hmac, JAVA代碼是針對字節數組簽名返回字節數組, 所以這里對返回值需要處理一下, 處理成字節數組
<?php require_once DIR_SAL . 'util/BytesUtil.php'; require_once DIR_SAL . 'util/Base64Util.php'; class HmacSHA1Signature {public function computeSignature($key, $data) {$hash = $this->hmac ( $data, $key );$hash = str_split ( $hash );foreach ( $hash as $index => $value ) {$asc = ord ( $value );if ($asc > 128) {$hash [$index] = ord ( $value ) - 128 * 2;} else {$hash [$index] = ord ( $value );}}$bytes = Base64Util::encodeBase64($hash);return BytesUtil::toStr($bytes);}private function hmac($data, $key, $hashFunc = 'sha1', $rawOutput = true) {if (! in_array ( $hashFunc, hash_algos () )) {$hashFunc = 'sha1';}return hash_hmac ( $hashFunc, $data, $key, $rawOutput );} }JAVA代碼中還將結果的字節數組進行base64轉換
public static String toBase64String(byte[] binaryData) {String toBase64Result = null;try {toBase64Result = new String(Base64.encodeBase64(binaryData), ContentUtil.BYTE_CODE);} catch (UnsupportedEncodingException e) {LOG.debug(e.getMessage());}return toBase64Result;}這個轉碼方式符合base64的定義, 即將3個8位表示數據的方式轉變為4個6位標識數據, 即3*8=4*6, 這樣會多出若干字節值, 具體算法實現通過bing搜到的2篇文章中的JAVA代碼綜合起來實現 (直接使用base64對字符串編碼的結果和預期不符):
<?php class Base64Util {public static function encodeBase64($data) {$encodes = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";require_once DIR_VENTOR . 'sal/util/BytesUtil.php';$encodes = BytesUtil::getBytes_10 ( $encodes );$dataLength = intval ( count ( $data ) );$modulus = intval ( $dataLength % 3 );//計算結果應有位數if ($modulus == 0) {//byte位數能被3整除$sbLength = intval ( (4 * $dataLength) / 3 );} else {$sbLength = intval ( 4 * (intval ( ($dataLength / 3) ) + 1) );}$sb = array ();$pos = 0;$val = 0;foreach ( $data as $i => $byte ) {$val = ($val << 8) | ($data [$i] & 0xFF);$pos += 8;while ( $pos > 5 ) {$index = $val >> ($pos -= 6);$sb [] = $encodes [$index];$val &= ((1 << $pos) - 1);}}if ($pos > 0) {$index = $val << (6 - $pos);$sb [] = $encodes [$index];}//位數不夠的用=字符(ascII值為61)填充$real = count ( $sb );if ($real < $sbLength) {for($i = 0; $i < $sbLength - $real; $i ++) {$sb [] = 61;}}return $sb;} }
轉載于:https://www.cnblogs.com/Moon-Face/p/4496453.html
總結
以上是生活随笔為你收集整理的一段JAVA签名算法的PHP改写的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: js/jquery判断浏览器的方法总结
- 下一篇: PHP设计模式——享元模式