/* * Copyright 2011 Future Systems * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.krakenapps.webconsole.impl; import java.io.IOException; import java.nio.charset.Charset; import java.util.Map; import java.util.UUID; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.JsonProcessingException; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.type.TypeReference; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.handler.codec.base64.Base64; import org.krakenapps.msgbus.Message; import org.krakenapps.msgbus.Session; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class KrakenMessageDecoder { private KrakenMessageDecoder() { } public static Message decode(Session session, String text) { Logger logger = LoggerFactory.getLogger(KrakenMessageDecoder.class.getName()); Charset utf8 = Charset.forName("utf-8"); // remove potential control characters text = text.trim(); if (text.length() == 0) return null; if (logger.isDebugEnabled()) logger.debug("kraken webconsole: debug websocket frame length {}, json [{}]", text.length(), text); if (text.equals("ping")) return null; // decrypt if msg is encrypted if (session.has("enc_key")) { try { // jackson JsonNode container = new ObjectMapper().readTree(text); // 같은 작업 찾아야 할 부분 // jackson Map<String, Object> header = new ObjectMapper().readValue(container.get(0), new TypeReference<Map<String, Object>>() { }); Map<String, Object> body = new ObjectMapper().readValue(container.get(1), new TypeReference<Map<String, Object>>() { }); if (header.containsKey("iv") && body.containsKey("data")) { String data = body.get("data").toString(); byte[] iv = ByteUtil.asArray(Base64.decode(ChannelBuffers.wrappedBuffer(header.get("iv").toString() .getBytes()))); byte[] buf = ByteUtil.asArray(Base64.decode(ChannelBuffers.wrappedBuffer(data.getBytes()))); byte[] key = ByteUtil.asByteArray(UUID.fromString(session.getString("enc_key"))); SecretKeySpec secret = new SecretKeySpec(key, "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv)); byte[] plain = new byte[cipher.getOutputSize(buf.length)]; int plainLength = cipher.update(buf, 0, buf.length, plain, 0); plainLength += cipher.doFinal(plain, plainLength); text = new String(plain, 0, plainLength, utf8); logger.trace("kraken webconsole: decrypted msg [{}]", text); } } catch (Exception e) { logger.error("kraken webconsole: cannot decode encrypted msg [" + text + "]", e); } } try { // jackson JsonNode container = new ObjectMapper().readTree(text); // 같은 작업 찾아야 할 부분 // jackson Map<String, Object> header = new ObjectMapper().readValue(container.get(0), new TypeReference<Map<String, Object>>() { }); Map<String, Object> body = new ObjectMapper().readValue(container.get(1), new TypeReference<Map<String, Object>>() { }); Message msg = new Message(); msg.setGuid((String) header.get("guid")); msg.setType(Message.Type.valueOf((String) header.get("type"))); msg.setSource((String) header.get("source")); msg.setTarget((String) header.get("target")); msg.setMethod((String) header.get("method")); msg.setParameters(body); return msg; } catch (JsonProcessingException e) { logger.error("kraken webconsoke: invalid json Processing", e); } catch (IOException e) { logger.error("kraken webconsoke: invalid json read", e); } return null; } }