public function putObjectByContentSecurely($args = array()) { $sek = EncryptionUtil::genereateOnceUsedKey(); $encryptedSek = EncryptionUtil::encodeCek($this->encryptionMaterials, $sek); $content = $args["Content"]; if (empty($content)) { throw new Ks3ClientException("please specifie Content in request args"); } $metaContentLength = EncryptionUtil::metaTextLength($args); $plainTextLength = strlen($content); if ($metaContentLength > 0 && $metaContentLength < $plainTextLength) { $plainTextLength = $metaContentLength; } if ($plainTextLength > 0) { $args["UserMeta"]["x-kss-meta-x-kss-unencrypted-content-length"] = $plainTextLength; } else { throw new Ks3ClientException("unexpected content length " . $plainTextLength); } $content = substr($content, 0, $plainTextLength); $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, ''); $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND); mcrypt_generic_init($td, $sek, $iv); //对content进行pkcs5填充 $content = EncryptionUtil::PKCS5Padding($content, mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC)); $encrypted = mcrypt_generic($td, $content); mcrypt_generic_deinit($td); $args["ObjectMeta"]["Content-Length"] = strlen($encrypted); $args["Content"] = $encrypted; $args = EncryptionUtil::updateContentMD5Header($args); //TODO $matdesc = "{}"; if (ENCRYPTPTION_STORAGE_MODE == "ObjectMetadata") { $args["UserMeta"]["x-kss-meta-x-kss-key"] = base64_encode($encryptedSek); $args["UserMeta"]["x-kss-meta-x-kss-iv"] = base64_encode($iv); $args["UserMeta"]["x-kss-meta-x-kss-matdesc"] = $matdesc; } $result = $this->ks3client->putObjectByContent($args); if (ENCRYPTPTION_STORAGE_MODE == "InstructionFile") { $req = EncryptionUtil::createInstructionFile($args["Bucket"], $args["Key"], base64_encode($encryptedSek), base64_encode($iv), $matdesc); $this->ks3client->putObjectByContent($req); } return $result; }
public function streaming_read_callback($curl_handle, $file_handle, $length, $read_stream, $seek_position) { // Once we've sent as much as we're supposed to send... if ($this->hasread >= $this->contentLength) { // Send EOF return ''; } // If we're at the beginning of an upload and need to seek... if ($this->hasread == 0 && $seek_position > 0 && $seek_position !== ftell($read_stream)) { if (fseek($read_stream, $seek_position) !== 0) { throw new RequestCore_Exception('The stream does not support seeking and is either not at the requested position or the position is unknown.'); } } $blocksize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB); $needRead = min($this->contentLength - $this->hasread, $length); $read = fread($read_stream, $needRead); $this->hasread += strlen($read); $isLast = FALSE; if ($this->hasread >= $this->contentLength) { $isLast = TRUE; } $data = $this->buffer . $read; $dataLength = strlen($data); if (!$isLast) { $this->buffer = substr($data, $dataLength - $dataLength % $blocksize); $data = substr($data, 0, $dataLength - $dataLength % $blocksize); } else { //分块上传除最后一块外肯定是blocksize大小的倍数,所以不需要填充。 if ($this->mutipartUpload) { if ($this->isLastPart) { $this->buffer = NULL; $data = EncryptionUtil::PKCS5Padding($data, $blocksize); } else { //donothing } } else { $this->buffer = NULL; $data = EncryptionUtil::PKCS5Padding($data, $blocksize); } } $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, ''); mcrypt_generic_init($td, $this->cek, $this->iv); $encrypted = mcrypt_generic($td, $data); mcrypt_generic_deinit($td); //去除自动填充的16个字节//php的当恰好为16的倍数时竟然不填充? //$encrypted = substr($encrypted,0,strlen($encrypted)-$blocksize); //取最后一个block作为下一次的iv $this->iv = substr($encrypted, strlen($encrypted) - $blocksize); return $encrypted; }