一段JAVA簽名演算法的PHP改寫

來源:互聯網
上載者:User

標籤:

原始碼是這樣的:

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";    @Override    public String getAlgorithm() {        return ALGORITHM;    }    @Override    public 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代碼是針對位元組數組簽名返回位元組數組, 所以這裡對傳回值需要處理一下, 處理成位元組數組

<?phprequire_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對字串編碼的結果和預期不符):

<?phpclass 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;}}

  

一段JAVA簽名演算法的PHP改寫

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.